Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ecdbd9e06 | ||
|
|
a90e3d611c | ||
|
|
d49d638253 | ||
|
|
83338a56c0 | ||
|
|
562020de70 | ||
|
|
044907edeb | ||
|
|
cfa1aa87fc | ||
|
|
0ac32ee474 | ||
|
|
de0675f850 | ||
|
|
1c529790f2 | ||
|
|
40bcc4d572 | ||
|
|
58f109e79c | ||
|
|
cb324f6269 | ||
|
|
7cafaf5cbc | ||
|
|
a394952630 | ||
|
|
68e87f20aa | ||
|
|
64ed0b3e94 | ||
|
|
fcaaee958d | ||
|
|
29e356ff86 | ||
|
|
460edc7bc7 | ||
|
|
582c7af12d | ||
|
|
e1a78382c3 | ||
|
|
4ee1693434 | ||
|
|
1ba63a2175 | ||
|
|
b5551fd8ba | ||
|
|
fac0038af8 | ||
|
|
ee6685e324 | ||
|
|
0fb18f995c | ||
|
|
5e6160149f | ||
|
|
be66c563a8 |
@@ -99,6 +99,7 @@ import { getSidebarLinks } from '../utils'
|
|||||||
import { usersStore } from '@/stores/user'
|
import { usersStore } from '@/stores/user'
|
||||||
import { sessionStore } from '@/stores/session'
|
import { sessionStore } from '@/stores/session'
|
||||||
import { useSidebar } from '@/stores/sidebar'
|
import { useSidebar } from '@/stores/sidebar'
|
||||||
|
import { useSettings } from '@/stores/settings'
|
||||||
import { ChevronRight, Plus } from 'lucide-vue-next'
|
import { ChevronRight, Plus } from 'lucide-vue-next'
|
||||||
import { createResource, Button } from 'frappe-ui'
|
import { createResource, Button } from 'frappe-ui'
|
||||||
import PageModal from '@/components/Modals/PageModal.vue'
|
import PageModal from '@/components/Modals/PageModal.vue'
|
||||||
@@ -114,6 +115,7 @@ const isModerator = ref(false)
|
|||||||
const isInstructor = ref(false)
|
const isInstructor = ref(false)
|
||||||
const pageToEdit = ref(null)
|
const pageToEdit = ref(null)
|
||||||
const showWebPages = ref(false)
|
const showWebPages = ref(false)
|
||||||
|
const settingsStore = useSettings()
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
socket.on('publish_lms_notifications', (data) => {
|
socket.on('publish_lms_notifications', (data) => {
|
||||||
@@ -183,6 +185,28 @@ 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
|
||||||
|
}
|
||||||
|
|
||||||
|
sidebarLinks.value.splice(index, 0, {
|
||||||
|
label: 'Programs',
|
||||||
|
icon: 'Route',
|
||||||
|
to: 'Programs',
|
||||||
|
activeFor: activeFor,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const openPageModal = (link) => {
|
const openPageModal = (link) => {
|
||||||
showPageModal.value = true
|
showPageModal.value = true
|
||||||
pageToEdit.value = link
|
pageToEdit.value = link
|
||||||
@@ -215,6 +239,7 @@ watch(userResource, () => {
|
|||||||
isModerator.value = userResource.data.is_moderator
|
isModerator.value = userResource.data.is_moderator
|
||||||
isInstructor.value = userResource.data.is_instructor
|
isInstructor.value = userResource.data.is_instructor
|
||||||
addQuizzes()
|
addQuizzes()
|
||||||
|
addPrograms()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@
|
|||||||
{{ option.label }}
|
{{ option.label }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="option.label != option.description"
|
v-if="option.description"
|
||||||
class="text-xs text-gray-700"
|
class="text-xs text-gray-700"
|
||||||
v-html="option.description"
|
v-html="option.description"
|
||||||
></div>
|
></div>
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Autocomplete>
|
</Autocomplete>
|
||||||
|
<p v-if="description" class="text-sm text-gray-600">{{ description }}</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -67,6 +68,10 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue', 'change'])
|
const emit = defineEmits(['update:modelValue', 'change'])
|
||||||
@@ -118,7 +123,7 @@ const options = createResource({
|
|||||||
transform: (data) => {
|
transform: (data) => {
|
||||||
return data.map((option) => {
|
return data.map((option) => {
|
||||||
return {
|
return {
|
||||||
label: option.value,
|
label: option.label || option.value,
|
||||||
value: option.value,
|
value: option.value,
|
||||||
description: option.description,
|
description: option.description,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -303,9 +303,9 @@ const trashChapter = (chapterName) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const redirectToChapter = (chapter) => {
|
const redirectToChapter = (chapter) => {
|
||||||
|
if (!chapter.is_scorm_package) return
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
if (props.allowEdit) return
|
if (props.allowEdit) return
|
||||||
if (!chapter.is_scorm_package) return
|
|
||||||
if (!user.data) {
|
if (!user.data) {
|
||||||
showToast(
|
showToast(
|
||||||
__('You are not enrolled'),
|
__('You are not enrolled'),
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<AppSidebar />
|
<AppSidebar />
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full overflow-auto" id="scrollContainer">
|
<div class="w-full overflow-auto" id="scrollContainer">
|
||||||
|
<OnboardingBanner />
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -16,4 +17,5 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import AppSidebar from './AppSidebar.vue'
|
import AppSidebar from './AppSidebar.vue'
|
||||||
|
import OnboardingBanner from '@/components/OnboardingBanner.vue'
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -17,10 +17,15 @@
|
|||||||
<template #body-content>
|
<template #body-content>
|
||||||
<div class="space-y-4 text-base">
|
<div class="space-y-4 text-base">
|
||||||
<FormControl label="Title" v-model="chapter.title" :required="true" />
|
<FormControl label="Title" v-model="chapter.title" :required="true" />
|
||||||
<FormControl
|
<Switch
|
||||||
:label="__('Is SCORM Package')"
|
size="sm"
|
||||||
|
:label="__('SCORM Package')"
|
||||||
|
:description="
|
||||||
|
__(
|
||||||
|
'Enable this only if you want to upload a SCORM package as a chapter.'
|
||||||
|
)
|
||||||
|
"
|
||||||
v-model="chapter.is_scorm_package"
|
v-model="chapter.is_scorm_package"
|
||||||
type="checkbox"
|
|
||||||
/>
|
/>
|
||||||
<div v-if="chapter.is_scorm_package">
|
<div v-if="chapter.is_scorm_package">
|
||||||
<FileUploader
|
<FileUploader
|
||||||
@@ -70,14 +75,17 @@ import {
|
|||||||
Dialog,
|
Dialog,
|
||||||
FileUploader,
|
FileUploader,
|
||||||
FormControl,
|
FormControl,
|
||||||
|
Switch,
|
||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
import { defineModel, reactive, watch, ref } from 'vue'
|
import { defineModel, reactive, watch } from 'vue'
|
||||||
import { showToast, getFileSize } from '@/utils/'
|
import { showToast, getFileSize } from '@/utils/'
|
||||||
import { capture } from '@/telemetry'
|
import { capture } from '@/telemetry'
|
||||||
import { FileText, X } from 'lucide-vue-next'
|
import { FileText, X } from 'lucide-vue-next'
|
||||||
|
import { useSettings } from '@/stores/settings'
|
||||||
|
|
||||||
const show = defineModel()
|
const show = defineModel()
|
||||||
const outline = defineModel('outline')
|
const outline = defineModel('outline')
|
||||||
|
const settingsStore = useSettings()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
course: {
|
course: {
|
||||||
@@ -137,6 +145,9 @@ const addChapter = async (close) => {
|
|||||||
{
|
{
|
||||||
onSuccess(data) {
|
onSuccess(data) {
|
||||||
cleanChapter()
|
cleanChapter()
|
||||||
|
if (!settingsStore.onboardingDetails.data?.is_onboarded) {
|
||||||
|
settingsStore.onboardingDetails.reload()
|
||||||
|
}
|
||||||
outline.value.reload()
|
outline.value.reload()
|
||||||
showToast(
|
showToast(
|
||||||
__('Success'),
|
__('Success'),
|
||||||
|
|||||||
@@ -108,9 +108,31 @@ const tabsStructure = computed(() => {
|
|||||||
hideLabel: true,
|
hideLabel: true,
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
label: 'Members',
|
label: 'General',
|
||||||
description: 'Manage the members of your learning system',
|
icon: 'Wrench',
|
||||||
icon: 'UserRoundPlus',
|
fields: [
|
||||||
|
{
|
||||||
|
label: 'Enable Learning Paths',
|
||||||
|
name: 'enable_learning_paths',
|
||||||
|
description:
|
||||||
|
'This will enforce students to go through programs assigned to them in the correct order.',
|
||||||
|
type: 'checkbox',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Send calendar invite for evaluations',
|
||||||
|
name: 'send_calendar_invite_for_evaluations',
|
||||||
|
description:
|
||||||
|
'If enabled, it sends google calendar invite to the student for evaluations.',
|
||||||
|
type: 'checkbox',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Unsplash Access Key',
|
||||||
|
name: 'unsplash_access_key',
|
||||||
|
description:
|
||||||
|
'Optional. If this is set, students can pick a cover image from the unsplash library for their profile page. https://unsplash.com/documentation#getting-started.',
|
||||||
|
type: 'text',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -156,9 +178,14 @@ const tabsStructure = computed(() => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Settings',
|
label: 'Lists',
|
||||||
hideLabel: true,
|
hideLabel: false,
|
||||||
items: [
|
items: [
|
||||||
|
{
|
||||||
|
label: 'Members',
|
||||||
|
description: 'Manage the members of your learning system',
|
||||||
|
icon: 'UserRoundPlus',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: 'Categories',
|
label: 'Categories',
|
||||||
description: 'Manage the members of your learning system',
|
description: 'Manage the members of your learning system',
|
||||||
|
|||||||
151
frontend/src/components/OnboardingBanner.vue
Normal file
151
frontend/src/components/OnboardingBanner.vue
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="showOnboardingBanner && onboardingDetails.data">
|
||||||
|
<Tooltip :text="__('Skip Onboarding')" placement="left">
|
||||||
|
<X
|
||||||
|
class="w-4 h-4 stroke-1 absolute top-2 right-2 cursor-pointer mr-1"
|
||||||
|
@click="skipOnboarding.reload()"
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
<div class="flex items-center justify-evenly bg-gray-100 p-10">
|
||||||
|
<div
|
||||||
|
@click="redirectToCourseForm()"
|
||||||
|
class="flex items-center space-x-2"
|
||||||
|
:class="{
|
||||||
|
'cursor-pointer': !onboardingDetails.data.course_created.length,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
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" />
|
||||||
|
</span>
|
||||||
|
<span v-else class="font-semibold bg-white px-2 py-1 rounded-full">
|
||||||
|
1
|
||||||
|
</span>
|
||||||
|
<span class="text-lg font-semibold">
|
||||||
|
{{ __('Create a course') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
@click="redirectToChapterForm()"
|
||||||
|
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,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
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" />
|
||||||
|
</span>
|
||||||
|
<span v-else class="font-semibold bg-white px-2 py-1 rounded-full">
|
||||||
|
2
|
||||||
|
</span>
|
||||||
|
<span class="text-lg font-semibold">
|
||||||
|
{{ __('Add a chapter') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
@click="redirectToLessonForm()"
|
||||||
|
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.chapter_created.length,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
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" />
|
||||||
|
</span>
|
||||||
|
<span class="font-semibold bg-white px-2 py-1 rounded-full"> 3 </span>
|
||||||
|
<span class="text-lg font-semibold">
|
||||||
|
{{ __('Add a lesson') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import { Check, X } from 'lucide-vue-next'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useSettings } from '@/stores/settings'
|
||||||
|
import { createResource, Tooltip } from 'frappe-ui'
|
||||||
|
|
||||||
|
const showOnboardingBanner = ref(false)
|
||||||
|
const settings = useSettings()
|
||||||
|
const onboardingDetails = settings.onboardingDetails
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
watch(onboardingDetails, () => {
|
||||||
|
if (!onboardingDetails.data?.is_onboarded) {
|
||||||
|
showOnboardingBanner.value = true
|
||||||
|
} else {
|
||||||
|
showOnboardingBanner.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const redirectToCourseForm = () => {
|
||||||
|
if (onboardingDetails.data?.course_created.length) {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
router.push({ name: 'CourseForm', params: { courseName: 'new' } })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const redirectToChapterForm = () => {
|
||||||
|
if (!onboardingDetails.data?.course_created.length) {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
router.push({
|
||||||
|
name: 'CourseForm',
|
||||||
|
params: {
|
||||||
|
courseName: onboardingDetails.data?.first_course,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const redirectToLessonForm = () => {
|
||||||
|
if (!onboardingDetails.data?.course_created.length) {
|
||||||
|
return
|
||||||
|
} else if (!onboardingDetails.data?.chapter_created.length) {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
router.push({
|
||||||
|
name: 'LessonForm',
|
||||||
|
params: {
|
||||||
|
courseName: onboardingDetails.data?.first_course,
|
||||||
|
chapterNumber: 1,
|
||||||
|
lessonNumber: 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const skipOnboarding = createResource({
|
||||||
|
url: 'frappe.client.set_value',
|
||||||
|
makeParams() {
|
||||||
|
return {
|
||||||
|
doctype: 'LMS Settings',
|
||||||
|
name: 'LMS Settings',
|
||||||
|
fieldname: 'is_onboarding_complete',
|
||||||
|
value: 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSuccess(data) {
|
||||||
|
onboardingDetails.reload()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -397,6 +397,9 @@ const attempts = createResource({
|
|||||||
watch(
|
watch(
|
||||||
() => quiz.data,
|
() => quiz.data,
|
||||||
() => {
|
() => {
|
||||||
|
if (quiz.data) {
|
||||||
|
populateQuestions()
|
||||||
|
}
|
||||||
if (quiz.data && quiz.data.max_attempts) {
|
if (quiz.data && quiz.data.max_attempts) {
|
||||||
attempts.reload()
|
attempts.reload()
|
||||||
resetQuiz()
|
resetQuiz()
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Button, Badge } from 'frappe-ui'
|
import { Button, Badge } from 'frappe-ui'
|
||||||
import SettingFields from '@/components/SettingFields.vue'
|
import SettingFields from '@/components/SettingFields.vue'
|
||||||
|
import { showToast } from '@/utils'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
fields: {
|
fields: {
|
||||||
@@ -54,7 +55,14 @@ const update = () => {
|
|||||||
props.data.doc[f.name] = f.value
|
props.data.doc[f.name] = f.value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
props.data.save.submit()
|
props.data.save.submit(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
onError(err) {
|
||||||
|
showToast('Error', err.messages?.[0] || err, 'x')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -90,6 +90,7 @@
|
|||||||
:type="field.type"
|
:type="field.type"
|
||||||
:rows="field.rows"
|
:rows="field.rows"
|
||||||
:options="field.options"
|
:options="field.options"
|
||||||
|
:description="field.description"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -100,7 +101,7 @@
|
|||||||
import { FormControl, FileUploader, Button, Switch } from 'frappe-ui'
|
import { FormControl, FileUploader, Button, Switch } from 'frappe-ui'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { getFileSize, validateFile } from '@/utils'
|
import { getFileSize, validateFile } from '@/utils'
|
||||||
import { X, FileText } from 'lucide-vue-next'
|
import { X } from 'lucide-vue-next'
|
||||||
import Link from '@/components/Controls/Link.vue'
|
import Link from '@/components/Controls/Link.vue'
|
||||||
import CodeEditor from '@/components/Controls/CodeEditor.vue'
|
import CodeEditor from '@/components/Controls/CodeEditor.vue'
|
||||||
|
|
||||||
|
|||||||
@@ -434,6 +434,9 @@ const submitCourse = () => {
|
|||||||
onSuccess(data) {
|
onSuccess(data) {
|
||||||
capture('course_created')
|
capture('course_created')
|
||||||
showToast('Success', 'Course created successfully', 'check')
|
showToast('Success', 'Course created successfully', 'check')
|
||||||
|
if (!settingsStore.onboardingDetails.data?.is_onboarded) {
|
||||||
|
settingsStore.onboardingDetails.reload()
|
||||||
|
}
|
||||||
router.push({
|
router.push({
|
||||||
name: 'CourseForm',
|
name: 'CourseForm',
|
||||||
params: { courseName: data.name },
|
params: { courseName: data.name },
|
||||||
|
|||||||
@@ -160,30 +160,45 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import {
|
||||||
Breadcrumbs,
|
|
||||||
Tabs,
|
|
||||||
Badge,
|
Badge,
|
||||||
|
Breadcrumbs,
|
||||||
Button,
|
Button,
|
||||||
FormControl,
|
call,
|
||||||
createResource,
|
createResource,
|
||||||
|
FormControl,
|
||||||
|
Tabs,
|
||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
import CourseCard from '@/components/CourseCard.vue'
|
import CourseCard from '@/components/CourseCard.vue'
|
||||||
import { BookOpen, Plus, Search } from 'lucide-vue-next'
|
import { BookOpen, Plus, Search } from 'lucide-vue-next'
|
||||||
import { ref, computed, inject, onMounted, watch } from 'vue'
|
import { ref, computed, inject, onMounted, watch } from 'vue'
|
||||||
import { updateDocumentTitle } from '@/utils'
|
import { updateDocumentTitle } from '@/utils'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useSettings } from '@/stores/settings'
|
||||||
|
|
||||||
const user = inject('$user')
|
const user = inject('$user')
|
||||||
const searchQuery = ref('')
|
const searchQuery = ref('')
|
||||||
const currentCategory = ref(null)
|
const currentCategory = ref(null)
|
||||||
const hasCourses = ref(false)
|
const hasCourses = ref(false)
|
||||||
|
const router = useRouter()
|
||||||
|
const settings = useSettings()
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
checkLearningPath()
|
||||||
let queries = new URLSearchParams(location.search)
|
let queries = new URLSearchParams(location.search)
|
||||||
if (queries.has('category')) {
|
if (queries.has('category')) {
|
||||||
currentCategory.value = queries.get('category')
|
currentCategory.value = queries.get('category')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const checkLearningPath = () => {
|
||||||
|
if (
|
||||||
|
settings.learningPaths.data &&
|
||||||
|
(!user.data?.is_moderator || !user.data?.is_instructor)
|
||||||
|
) {
|
||||||
|
router.push({ name: 'Programs' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const courses = createResource({
|
const courses = createResource({
|
||||||
url: 'lms.lms.utils.get_courses',
|
url: 'lms.lms.utils.get_courses',
|
||||||
cache: ['courses', user.data?.email],
|
cache: ['courses', user.data?.email],
|
||||||
|
|||||||
@@ -92,11 +92,13 @@ import LessonHelp from '@/components/LessonHelp.vue'
|
|||||||
import { ChevronRight } from 'lucide-vue-next'
|
import { ChevronRight } from 'lucide-vue-next'
|
||||||
import { updateDocumentTitle, createToast, getEditorTools } from '@/utils'
|
import { updateDocumentTitle, createToast, getEditorTools } from '@/utils'
|
||||||
import { capture } from '@/telemetry'
|
import { capture } from '@/telemetry'
|
||||||
|
import { useSettings } from '@/stores/settings'
|
||||||
|
|
||||||
const editor = ref(null)
|
const editor = ref(null)
|
||||||
const instructorEditor = ref(null)
|
const instructorEditor = ref(null)
|
||||||
const user = inject('$user')
|
const user = inject('$user')
|
||||||
const openInstructorEditor = ref(false)
|
const openInstructorEditor = ref(false)
|
||||||
|
const settingsStore = useSettings()
|
||||||
let autoSaveInterval
|
let autoSaveInterval
|
||||||
let showSuccessMessage = false
|
let showSuccessMessage = false
|
||||||
|
|
||||||
@@ -393,6 +395,9 @@ const createNewLesson = () => {
|
|||||||
onSuccess() {
|
onSuccess() {
|
||||||
capture('lesson_created')
|
capture('lesson_created')
|
||||||
showToast('Success', 'Lesson created successfully', 'check')
|
showToast('Success', 'Lesson created successfully', 'check')
|
||||||
|
if (!settingsStore.onboardingDetails.data?.is_onboarded) {
|
||||||
|
settingsStore.onboardingDetails.reload()
|
||||||
|
}
|
||||||
lessonDetails.reload()
|
lessonDetails.reload()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
354
frontend/src/pages/ProgramForm.vue
Normal file
354
frontend/src/pages/ProgramForm.vue
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
<template>
|
||||||
|
<header
|
||||||
|
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">
|
||||||
|
{{ __('Save') }}
|
||||||
|
</Button>
|
||||||
|
</header>
|
||||||
|
<div v-if="program.doc" class="pt-5 px-5 w-3/4 mx-auto space-y-10">
|
||||||
|
<FormControl v-model="program.doc.title" :label="__('Title')" />
|
||||||
|
|
||||||
|
<!-- Courses -->
|
||||||
|
<div>
|
||||||
|
<div class="flex items-center justify-between mb-2">
|
||||||
|
<div class="text-lg font-semibold">
|
||||||
|
{{ __('Program Courses') }}
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
currentForm = 'course'
|
||||||
|
showDialog = true
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<Plus class="w-4 h-4" />
|
||||||
|
</template>
|
||||||
|
{{ __('Add') }}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
:columns="courseColumns"
|
||||||
|
:rows="program.doc.program_courses"
|
||||||
|
row-key="name"
|
||||||
|
:options="{
|
||||||
|
showTooltip: false,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<ListHeader
|
||||||
|
class="mb-2 grid items-center space-x-4 rounded bg-gray-100 p-2"
|
||||||
|
>
|
||||||
|
<ListHeaderItem :item="item" v-for="item in courseColumns" />
|
||||||
|
</ListHeader>
|
||||||
|
<ListRows>
|
||||||
|
<Draggable
|
||||||
|
:list="program.doc.program_courses"
|
||||||
|
item-key="name"
|
||||||
|
group="items"
|
||||||
|
@end="updateOrder"
|
||||||
|
>
|
||||||
|
<template #item="{ element: row }">
|
||||||
|
<ListRow :row="row" />
|
||||||
|
</template>
|
||||||
|
</Draggable>
|
||||||
|
</ListRows>
|
||||||
|
<ListSelectBanner>
|
||||||
|
<template #actions="{ unselectAll, selections }">
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
@click="remove(selections, unselectAll, 'program_courses')"
|
||||||
|
>
|
||||||
|
<Trash2 class="h-4 w-4 stroke-1.5" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ListSelectBanner>
|
||||||
|
</ListView>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Members -->
|
||||||
|
<div>
|
||||||
|
<div class="flex items-center justify-between mb-2">
|
||||||
|
<div class="text-lg font-semibold">
|
||||||
|
{{ __('Program Members') }}
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
currentForm = 'member'
|
||||||
|
showDialog = true
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<Plus class="w-4 h-4" />
|
||||||
|
</template>
|
||||||
|
{{ __('Add') }}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
:columns="memberColumns"
|
||||||
|
:rows="program.doc.program_members"
|
||||||
|
row-key="name"
|
||||||
|
:options="{
|
||||||
|
showTooltip: false,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<ListHeader
|
||||||
|
class="mb-2 grid items-center space-x-4 rounded bg-gray-100 p-2"
|
||||||
|
>
|
||||||
|
<ListHeaderItem :item="item" v-for="item in memberColumns" />
|
||||||
|
</ListHeader>
|
||||||
|
<ListRows>
|
||||||
|
<ListRow :row="row" v-for="row in program.doc.program_members" />
|
||||||
|
</ListRows>
|
||||||
|
<ListSelectBanner>
|
||||||
|
<template #actions="{ unselectAll, selections }">
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
@click="remove(selections, unselectAll, 'program_members')"
|
||||||
|
>
|
||||||
|
<Trash2 class="h-4 w-4 stroke-1.5" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ListSelectBanner>
|
||||||
|
</ListView>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Dialog
|
||||||
|
v-model="showDialog"
|
||||||
|
:options="{
|
||||||
|
title:
|
||||||
|
currentForm == 'course'
|
||||||
|
? __('New Program Course')
|
||||||
|
: __('New Program Member'),
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
label: __('Add'),
|
||||||
|
variant: 'solid',
|
||||||
|
onClick: () =>
|
||||||
|
currentForm == 'course'
|
||||||
|
? addProgramCourse(close)
|
||||||
|
: addProgramMember(close),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #body-content>
|
||||||
|
<Link
|
||||||
|
v-if="currentForm == 'course'"
|
||||||
|
v-model="course"
|
||||||
|
doctype="LMS Course"
|
||||||
|
:filters="{
|
||||||
|
disable_self_learning: 1,
|
||||||
|
}"
|
||||||
|
:label="__('Program Course')"
|
||||||
|
:description="
|
||||||
|
__(
|
||||||
|
'Only courses for which self learning is disabled can be added to program.'
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Link
|
||||||
|
v-if="currentForm == 'member'"
|
||||||
|
v-model="member"
|
||||||
|
doctype="User"
|
||||||
|
:filters="{
|
||||||
|
ignore_user_type: 1,
|
||||||
|
}"
|
||||||
|
:label="__('Program Member')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
Breadcrumbs,
|
||||||
|
Button,
|
||||||
|
call,
|
||||||
|
createDocumentResource,
|
||||||
|
Dialog,
|
||||||
|
FormControl,
|
||||||
|
ListView,
|
||||||
|
ListRows,
|
||||||
|
ListRow,
|
||||||
|
ListHeader,
|
||||||
|
ListHeaderItem,
|
||||||
|
ListSelectBanner,
|
||||||
|
} from 'frappe-ui'
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
import { Plus, Trash2 } from 'lucide-vue-next'
|
||||||
|
import Link from '@/components/Controls/Link.vue'
|
||||||
|
import { showToast } from '@/utils/'
|
||||||
|
import Draggable from 'vuedraggable'
|
||||||
|
|
||||||
|
const showDialog = ref(false)
|
||||||
|
const currentForm = ref(null)
|
||||||
|
const course = ref(null)
|
||||||
|
const member = ref(null)
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
programName: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const program = createDocumentResource({
|
||||||
|
doctype: 'LMS Program',
|
||||||
|
name: props.programName,
|
||||||
|
auto: true,
|
||||||
|
cache: ['program', props.programName],
|
||||||
|
})
|
||||||
|
|
||||||
|
const addProgramCourse = () => {
|
||||||
|
program.setValue.submit(
|
||||||
|
{
|
||||||
|
program_courses: [
|
||||||
|
...program.doc.program_courses,
|
||||||
|
{ course: course.value },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess(data) {
|
||||||
|
showDialog.value = false
|
||||||
|
course.value = null
|
||||||
|
showToast(__('Success'), __('Course added to program'), 'check')
|
||||||
|
program.reload()
|
||||||
|
},
|
||||||
|
onError(err) {
|
||||||
|
showToast('Error', err.messages?.[0] || err, 'x')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const addProgramMember = () => {
|
||||||
|
program.setValue.submit(
|
||||||
|
{
|
||||||
|
program_members: [
|
||||||
|
...program.doc.program_members,
|
||||||
|
{ member: member.value },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess(data) {
|
||||||
|
showDialog.value = false
|
||||||
|
member.value = null
|
||||||
|
showToast(__('Success'), __('Member added to program'), 'check')
|
||||||
|
program.reload()
|
||||||
|
},
|
||||||
|
onError(err) {
|
||||||
|
showToast('Error', err.messages?.[0] || err, 'x')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const remove = (selections, unselectAll, doctype) => {
|
||||||
|
selections = Array.from(selections)
|
||||||
|
program.setValue.submit(
|
||||||
|
{
|
||||||
|
[doctype]: program.doc[doctype].filter(
|
||||||
|
(row) => !selections.includes(row.name)
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess(data) {
|
||||||
|
unselectAll()
|
||||||
|
showToast(__('Success'), __('Items removed successfully'), 'check')
|
||||||
|
program.reload()
|
||||||
|
},
|
||||||
|
onError(err) {
|
||||||
|
showToast('Error', err.messages?.[0] || err, 'x')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateOrder = (e) => {
|
||||||
|
let sourceIdx = e.from.dataset.idx
|
||||||
|
let targetIdx = e.to.dataset.idx
|
||||||
|
let courses = program.doc.program_courses
|
||||||
|
courses.splice(targetIdx, 0, courses.splice(sourceIdx, 1)[0])
|
||||||
|
|
||||||
|
courses.forEach((course, index) => {
|
||||||
|
course.idx = index + 1
|
||||||
|
})
|
||||||
|
|
||||||
|
program.setValue.submit(
|
||||||
|
{
|
||||||
|
program_courses: courses,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess(data) {
|
||||||
|
showToast(__('Success'), __('Course moved successfully'), 'check')
|
||||||
|
program.reload()
|
||||||
|
},
|
||||||
|
onError(err) {
|
||||||
|
showToast('Error', err.messages?.[0] || err, 'x')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const courseColumns = computed(() => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: 'Title',
|
||||||
|
key: 'course_title',
|
||||||
|
width: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'ID',
|
||||||
|
key: 'course',
|
||||||
|
width: 3,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
const memberColumns = computed(() => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: 'Member',
|
||||||
|
key: 'member',
|
||||||
|
width: 3,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Full Name',
|
||||||
|
key: 'full_name',
|
||||||
|
width: 3,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Progress',
|
||||||
|
key: 'progress',
|
||||||
|
width: 3,
|
||||||
|
align: 'left',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
const breadbrumbs = computed(() => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: 'Programs',
|
||||||
|
route: { name: 'Programs' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: props.programName === 'new' ? 'New Program' : props.programName,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
</script>
|
||||||
185
frontend/src/pages/Programs.vue
Normal file
185
frontend/src/pages/Programs.vue
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
<template>
|
||||||
|
<header
|
||||||
|
class="sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5"
|
||||||
|
>
|
||||||
|
<Breadcrumbs :items="breadbrumbs" />
|
||||||
|
<Button
|
||||||
|
v-if="user.data?.is_moderator || user.data?.is_instructor"
|
||||||
|
@click="showDialog = true"
|
||||||
|
variant="solid"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<Plus class="h-4 w-4 stroke-1.5" />
|
||||||
|
</template>
|
||||||
|
{{ __('New') }}
|
||||||
|
</Button>
|
||||||
|
</header>
|
||||||
|
<div v-if="programs.data?.length" class="pt-5 px-5">
|
||||||
|
<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"
|
||||||
|
size="lg"
|
||||||
|
>
|
||||||
|
{{ program.members }}
|
||||||
|
{{
|
||||||
|
program.members == 1 ? __(singularize('members')) : __('members')
|
||||||
|
}}
|
||||||
|
</Badge>
|
||||||
|
<Badge
|
||||||
|
v-if="program.progress"
|
||||||
|
variant="subtle"
|
||||||
|
theme="blue"
|
||||||
|
size="lg"
|
||||||
|
>
|
||||||
|
{{ program.progress }}{{ __('% completed') }}
|
||||||
|
</Badge>
|
||||||
|
|
||||||
|
<router-link
|
||||||
|
v-if="user.data?.is_moderator || user.data?.is_instructor"
|
||||||
|
:to="{
|
||||||
|
name: 'ProgramForm',
|
||||||
|
params: { programName: program.name },
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<Button>
|
||||||
|
<template #prefix>
|
||||||
|
<Edit class="h-4 w-4 stroke-1.5" />
|
||||||
|
</template>
|
||||||
|
{{ __('Edit') }}
|
||||||
|
</Button>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
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>
|
||||||
|
<div v-else class="text-sm italic text-gray-600 mt-4">
|
||||||
|
{{ __('No courses in this program') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="text-center p-5 text-gray-600 mt-52 w-3/4 md:w-1/2 mx-auto space-y-2"
|
||||||
|
>
|
||||||
|
<BookOpen class="size-10 mx-auto stroke-1 text-gray-500" />
|
||||||
|
<div class="text-xl font-medium">
|
||||||
|
{{ __('No programs found') }}
|
||||||
|
</div>
|
||||||
|
<div class="leading-5">
|
||||||
|
{{
|
||||||
|
__(
|
||||||
|
'There are no programs available at the moment. Keep an eye out, fresh learning experiences are on the way soon!'
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Dialog
|
||||||
|
v-model="showDialog"
|
||||||
|
:options="{
|
||||||
|
title: __('New Program'),
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
label: __('Create'),
|
||||||
|
variant: 'solid',
|
||||||
|
onClick: () => createProgram(close),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #body-content>
|
||||||
|
<FormControl :label="__('Title')" v-model="title" />
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
Badge,
|
||||||
|
Breadcrumbs,
|
||||||
|
Button,
|
||||||
|
call,
|
||||||
|
createResource,
|
||||||
|
Dialog,
|
||||||
|
FormControl,
|
||||||
|
} from 'frappe-ui'
|
||||||
|
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)
|
||||||
|
const router = useRouter()
|
||||||
|
const title = ref('')
|
||||||
|
|
||||||
|
const programs = createResource({
|
||||||
|
url: 'lms.lms.utils.get_programs',
|
||||||
|
auto: true,
|
||||||
|
cache: 'programs',
|
||||||
|
})
|
||||||
|
|
||||||
|
const createProgram = (close) => {
|
||||||
|
call('frappe.client.insert', {
|
||||||
|
doc: {
|
||||||
|
doctype: 'LMS Program',
|
||||||
|
title: title.value,
|
||||||
|
},
|
||||||
|
}).then((res) => {
|
||||||
|
router.push({ name: 'ProgramForm', params: { programName: res.name } })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
</script>
|
||||||
@@ -182,6 +182,17 @@ const routes = [
|
|||||||
component: () => import('@/pages/QuizSubmission.vue'),
|
component: () => import('@/pages/QuizSubmission.vue'),
|
||||||
props: true,
|
props: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/programs/:programName',
|
||||||
|
name: 'ProgramForm',
|
||||||
|
component: () => import('@/pages/ProgramForm.vue'),
|
||||||
|
props: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/programs',
|
||||||
|
name: 'Programs',
|
||||||
|
component: () => import('@/pages/Programs.vue'),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
let router = createRouter({
|
let router = createRouter({
|
||||||
|
|||||||
@@ -1,12 +1,32 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
import { createResource } from 'frappe-ui'
|
||||||
|
|
||||||
export const useSettings = defineStore('settings', () => {
|
export const useSettings = defineStore('settings', () => {
|
||||||
const isSettingsOpen = ref(false)
|
const isSettingsOpen = ref(false)
|
||||||
const activeTab = ref(null)
|
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'],
|
||||||
|
})
|
||||||
|
|
||||||
|
const onboardingDetails = createResource({
|
||||||
|
url: 'lms.lms.utils.is_onboarding_complete',
|
||||||
|
auto: true,
|
||||||
|
cache: ['onboardingDetails'],
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isSettingsOpen,
|
isSettingsOpen,
|
||||||
activeTab,
|
activeTab,
|
||||||
|
learningPaths,
|
||||||
|
onboardingDetails,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
__version__ = "2.12.0"
|
__version__ = "2.13.0"
|
||||||
|
|||||||
@@ -66,7 +66,9 @@ def delete_lms_roles():
|
|||||||
|
|
||||||
|
|
||||||
def create_course_creator_role():
|
def create_course_creator_role():
|
||||||
if not frappe.db.exists("Role", "Course Creator"):
|
if frappe.db.exists("Role", "Course Creator"):
|
||||||
|
frappe.db.set_value("Role", "Course Creator", "desk_access", 0)
|
||||||
|
else:
|
||||||
role = frappe.get_doc(
|
role = frappe.get_doc(
|
||||||
{
|
{
|
||||||
"doctype": "Role",
|
"doctype": "Role",
|
||||||
@@ -79,7 +81,9 @@ def create_course_creator_role():
|
|||||||
|
|
||||||
|
|
||||||
def create_moderator_role():
|
def create_moderator_role():
|
||||||
if not frappe.db.exists("Role", "Moderator"):
|
if frappe.db.exists("Role", "Moderator"):
|
||||||
|
frappe.db.set_value("Role", "Moderator", "desk_access", 0)
|
||||||
|
else:
|
||||||
role = frappe.get_doc(
|
role = frappe.get_doc(
|
||||||
{
|
{
|
||||||
"doctype": "Role",
|
"doctype": "Role",
|
||||||
@@ -92,7 +96,9 @@ def create_moderator_role():
|
|||||||
|
|
||||||
|
|
||||||
def create_evaluator_role():
|
def create_evaluator_role():
|
||||||
if not frappe.db.exists("Role", "Batch Evaluator"):
|
if frappe.db.exists("Role", "Batch Evaluator"):
|
||||||
|
frappe.db.set_value("Role", "Batch Evaluator", "desk_access", 0)
|
||||||
|
else:
|
||||||
role = frappe.new_doc("Role")
|
role = frappe.new_doc("Role")
|
||||||
role.update(
|
role.update(
|
||||||
{
|
{
|
||||||
@@ -105,7 +111,9 @@ def create_evaluator_role():
|
|||||||
|
|
||||||
|
|
||||||
def create_lms_student_role():
|
def create_lms_student_role():
|
||||||
if not frappe.db.exists("Role", "LMS Student"):
|
if frappe.db.exists("Role", "LMS Student"):
|
||||||
|
frappe.db.set_value("Role", "LMS Student", "desk_access", 0)
|
||||||
|
else:
|
||||||
role = frappe.new_doc("Role")
|
role = frappe.new_doc("Role")
|
||||||
role.update(
|
role.update(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -93,15 +93,15 @@ def save_progress(lesson, course):
|
|||||||
|
|
||||||
frappe.db.set_value("LMS Enrollment", membership, "current_lesson", lesson)
|
frappe.db.set_value("LMS Enrollment", membership, "current_lesson", lesson)
|
||||||
|
|
||||||
quiz_completed = get_quiz_progress(lesson)
|
|
||||||
if not quiz_completed:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
if frappe.db.exists(
|
if frappe.db.exists(
|
||||||
"LMS Course Progress", {"lesson": lesson, "member": frappe.session.user}
|
"LMS Course Progress", {"lesson": lesson, "member": frappe.session.user}
|
||||||
):
|
):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
quiz_completed = get_quiz_progress(lesson)
|
||||||
|
if not quiz_completed:
|
||||||
|
return 0
|
||||||
|
|
||||||
frappe.get_doc(
|
frappe.get_doc(
|
||||||
{
|
{
|
||||||
"doctype": "LMS Course Progress",
|
"doctype": "LMS Course Progress",
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class LMSCourse(Document):
|
|||||||
frappe.throw(_("Please install the Payments app to create a paid courses."))
|
frappe.throw(_("Please install the Payments app to create a paid courses."))
|
||||||
|
|
||||||
def validate_amount_and_currency(self):
|
def validate_amount_and_currency(self):
|
||||||
if self.paid_course and (not self.amount and not self.currency):
|
if self.paid_course and (not self.course_price and not self.currency):
|
||||||
frappe.throw(_("Amount and currency are required for paid courses."))
|
frappe.throw(_("Amount and currency are required for paid courses."))
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
from frappe.utils import ceil
|
||||||
|
|
||||||
|
|
||||||
class LMSEnrollment(Document):
|
class LMSEnrollment(Document):
|
||||||
@@ -11,6 +12,9 @@ class LMSEnrollment(Document):
|
|||||||
self.validate_membership_in_same_batch()
|
self.validate_membership_in_same_batch()
|
||||||
self.validate_membership_in_different_batch_same_course()
|
self.validate_membership_in_different_batch_same_course()
|
||||||
|
|
||||||
|
def on_update(self):
|
||||||
|
self.update_program_progress()
|
||||||
|
|
||||||
def validate_membership_in_same_batch(self):
|
def validate_membership_in_same_batch(self):
|
||||||
filters = {"member": self.member, "course": self.course, "name": ["!=", self.name]}
|
filters = {"member": self.member, "course": self.course, "name": ["!=", self.name]}
|
||||||
if self.batch_old:
|
if self.batch_old:
|
||||||
@@ -55,6 +59,26 @@ class LMSEnrollment(Document):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def update_program_progress(self):
|
||||||
|
programs = frappe.get_all(
|
||||||
|
"LMS Program Member", {"member": self.member}, ["parent", "name"]
|
||||||
|
)
|
||||||
|
|
||||||
|
for program in programs:
|
||||||
|
total_progress = 0
|
||||||
|
courses = frappe.get_all(
|
||||||
|
"LMS Program Course", {"parent": program.parent}, pluck="course"
|
||||||
|
)
|
||||||
|
for course in courses:
|
||||||
|
progress = frappe.db.get_value(
|
||||||
|
"LMS Enrollment", {"course": course, "member": self.member}, "progress"
|
||||||
|
)
|
||||||
|
progress = progress or 0
|
||||||
|
total_progress += progress
|
||||||
|
|
||||||
|
average_progress = ceil(total_progress / len(courses))
|
||||||
|
frappe.db.set_value("LMS Program Member", program.name, "progress", average_progress)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def create_membership(
|
def create_membership(
|
||||||
|
|||||||
0
lms/lms/doctype/lms_program/__init__.py
Normal file
0
lms/lms/doctype/lms_program/__init__.py
Normal file
8
lms/lms/doctype/lms_program/lms_program.js
Normal file
8
lms/lms/doctype/lms_program/lms_program.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2024, Frappe and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
// frappe.ui.form.on("LMS Program", {
|
||||||
|
// refresh(frm) {
|
||||||
|
|
||||||
|
// },
|
||||||
|
// });
|
||||||
84
lms/lms/doctype/lms_program/lms_program.json
Normal file
84
lms/lms/doctype/lms_program/lms_program.json
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"allow_rename": 1,
|
||||||
|
"autoname": "field:title",
|
||||||
|
"creation": "2024-11-18 12:27:13.283169",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"title",
|
||||||
|
"program_courses",
|
||||||
|
"program_members"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "program_courses",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"label": "Program Courses",
|
||||||
|
"options": "LMS Program Course"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "program_members",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"label": "Program Members",
|
||||||
|
"options": "LMS Program Member"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "title",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Title",
|
||||||
|
"reqd": 1,
|
||||||
|
"unique": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2024-11-20 12:26:02.214628",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "LMS Program",
|
||||||
|
"naming_rule": "By fieldname",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Moderator",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Course Creator",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sort_field": "creation",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"states": []
|
||||||
|
}
|
||||||
32
lms/lms/doctype/lms_program/lms_program.py
Normal file
32
lms/lms/doctype/lms_program/lms_program.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Copyright (c) 2024, Frappe and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
|
||||||
|
class LMSProgram(Document):
|
||||||
|
def validate(self):
|
||||||
|
self.validate_program_courses()
|
||||||
|
self.validate_program_members()
|
||||||
|
|
||||||
|
def validate_program_courses(self):
|
||||||
|
courses = [row.course for row in self.program_courses]
|
||||||
|
duplicates = {course for course in courses if courses.count(course) > 1}
|
||||||
|
if len(duplicates):
|
||||||
|
frappe.throw(
|
||||||
|
_("Course {0} has already been added to this batch.").format(
|
||||||
|
frappe.bold(next(iter(duplicates)))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def validate_program_members(self):
|
||||||
|
members = [row.member for row in self.program_members]
|
||||||
|
duplicates = {member for member in members if members.count(member) > 1}
|
||||||
|
if len(duplicates):
|
||||||
|
frappe.throw(
|
||||||
|
_("Member {0} has already been added to this batch.").format(
|
||||||
|
frappe.bold(next(iter(duplicates)))
|
||||||
|
)
|
||||||
|
)
|
||||||
21
lms/lms/doctype/lms_program/test_lms_program.py
Normal file
21
lms/lms/doctype/lms_program/test_lms_program.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (c) 2024, Frappe and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.tests import IntegrationTestCase, UnitTestCase
|
||||||
|
|
||||||
|
|
||||||
|
# On IntegrationTestCase, the doctype test records and all
|
||||||
|
# link-field test record depdendencies are recursively loaded
|
||||||
|
# Use these module variables to add/remove to/from that list
|
||||||
|
EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
||||||
|
IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
||||||
|
|
||||||
|
|
||||||
|
class TestLMSProgram(UnitTestCase):
|
||||||
|
"""
|
||||||
|
Unit tests for LMSProgram.
|
||||||
|
Use this class for testing individual functions and methods.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pass
|
||||||
0
lms/lms/doctype/lms_program_course/__init__.py
Normal file
0
lms/lms/doctype/lms_program_course/__init__.py
Normal file
42
lms/lms/doctype/lms_program_course/lms_program_course.json
Normal file
42
lms/lms/doctype/lms_program_course/lms_program_course.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"allow_rename": 1,
|
||||||
|
"creation": "2024-11-18 12:27:37.030302",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"course",
|
||||||
|
"course_title"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "course",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Course",
|
||||||
|
"options": "LMS Course",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fetch_from": "course.title",
|
||||||
|
"fieldname": "course_title",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Course Title",
|
||||||
|
"read_only": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"istable": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2024-11-18 12:43:46.800199",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "LMS Program Course",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"sort_field": "creation",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"states": []
|
||||||
|
}
|
||||||
9
lms/lms/doctype/lms_program_course/lms_program_course.py
Normal file
9
lms/lms/doctype/lms_program_course/lms_program_course.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2024, Frappe and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
|
||||||
|
class LMSProgramCourse(Document):
|
||||||
|
pass
|
||||||
0
lms/lms/doctype/lms_program_member/__init__.py
Normal file
0
lms/lms/doctype/lms_program_member/__init__.py
Normal file
50
lms/lms/doctype/lms_program_member/lms_program_member.json
Normal file
50
lms/lms/doctype/lms_program_member/lms_program_member.json
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"allow_rename": 1,
|
||||||
|
"creation": "2024-11-18 12:29:13.615014",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"member",
|
||||||
|
"full_name",
|
||||||
|
"progress"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "member",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Member",
|
||||||
|
"options": "User",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fetch_from": "member.full_name",
|
||||||
|
"fieldname": "full_name",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Full Name",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "progress",
|
||||||
|
"fieldtype": "Int",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Progress"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"istable": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2024-11-21 12:51:31.882576",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "LMS Program Member",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"sort_field": "creation",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"states": []
|
||||||
|
}
|
||||||
9
lms/lms/doctype/lms_program_member/lms_program_member.py
Normal file
9
lms/lms/doctype/lms_program_member/lms_program_member.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2024, Frappe and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
|
||||||
|
class LMSProgramMember(Document):
|
||||||
|
pass
|
||||||
@@ -5,13 +5,15 @@
|
|||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
|
"general_tab",
|
||||||
"default_home",
|
"default_home",
|
||||||
|
"send_calendar_invite_for_evaluations",
|
||||||
"is_onboarding_complete",
|
"is_onboarding_complete",
|
||||||
"column_break_zdel",
|
"column_break_zdel",
|
||||||
|
"enable_learning_paths",
|
||||||
"unsplash_access_key",
|
"unsplash_access_key",
|
||||||
"livecode_url",
|
"livecode_url",
|
||||||
"section_break_szgq",
|
"section_break_szgq",
|
||||||
"send_calendar_invite_for_evaluations",
|
|
||||||
"show_day_view",
|
"show_day_view",
|
||||||
"column_break_2",
|
"column_break_2",
|
||||||
"show_dashboard",
|
"show_dashboard",
|
||||||
@@ -80,6 +82,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "mentor_request_section",
|
"fieldname": "mentor_request_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 1,
|
||||||
"label": "Mentor Request"
|
"label": "Mentor Request"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -127,6 +130,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "section_break_szgq",
|
"fieldname": "section_break_szgq",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 1,
|
||||||
"label": "Batch Settings"
|
"label": "Batch Settings"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -336,12 +340,23 @@
|
|||||||
"fieldname": "payments_app_is_not_installed",
|
"fieldname": "payments_app_is_not_installed",
|
||||||
"fieldtype": "HTML",
|
"fieldtype": "HTML",
|
||||||
"label": "Payments app is not installed"
|
"label": "Payments app is not installed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "enable_learning_paths",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Enable Learning Paths"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "general_tab",
|
||||||
|
"fieldtype": "Tab Break",
|
||||||
|
"label": "General"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-10-01 12:15:49.800242",
|
"modified": "2024-11-20 11:55:05.358421",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Settings",
|
"name": "LMS Settings",
|
||||||
@@ -356,6 +371,13 @@
|
|||||||
"role": "System Manager",
|
"role": "System Manager",
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"email": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"role": "LMS Student",
|
||||||
|
"share": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
|
|||||||
@@ -855,7 +855,10 @@ def get_telemetry_boot_info():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
def is_onboarding_complete():
|
def is_onboarding_complete():
|
||||||
|
if not has_course_moderator_role():
|
||||||
|
return {"is_onboarded": False}
|
||||||
course_created = frappe.db.a_row_exists("LMS Course")
|
course_created = frappe.db.a_row_exists("LMS Course")
|
||||||
chapter_created = frappe.db.a_row_exists("Course Chapter")
|
chapter_created = frappe.db.a_row_exists("Course Chapter")
|
||||||
lesson_created = frappe.db.a_row_exists("Course Lesson")
|
lesson_created = frappe.db.a_row_exists("Course Lesson")
|
||||||
@@ -1751,3 +1754,81 @@ def enroll_in_batch(batch, payment_name=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
student.save(ignore_permissions=True)
|
student.save(ignore_permissions=True)
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_programs():
|
||||||
|
if (
|
||||||
|
has_course_moderator_role()
|
||||||
|
or has_course_instructor_role()
|
||||||
|
or has_course_evaluator_role()
|
||||||
|
):
|
||||||
|
programs = frappe.get_all("LMS Program", fields=["name"])
|
||||||
|
else:
|
||||||
|
programs = frappe.get_all(
|
||||||
|
"LMS Program Member", {"member": frappe.session.user}, ["parent as name", "progress"]
|
||||||
|
)
|
||||||
|
|
||||||
|
for program in programs:
|
||||||
|
program_courses = frappe.get_all(
|
||||||
|
"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))
|
||||||
|
|
||||||
|
program.members = frappe.db.count("LMS Program Member", {"parent": program.name})
|
||||||
|
|
||||||
|
return programs
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def enroll_in_program_course(program, course):
|
||||||
|
enrollment = frappe.db.exists(
|
||||||
|
"LMS Enrollment", {"member": frappe.session.user, "course": course}
|
||||||
|
)
|
||||||
|
|
||||||
|
if enrollment:
|
||||||
|
enrollment = frappe.db.get_value(
|
||||||
|
"LMS Enrollment", enrollment, ["name", "current_lesson"], as_dict=1
|
||||||
|
)
|
||||||
|
enrollment.current_lesson = get_lesson_index(enrollment.current_lesson)
|
||||||
|
return enrollment
|
||||||
|
|
||||||
|
program_courses = frappe.get_all(
|
||||||
|
"LMS Program Course", {"parent": program}, ["course", "idx"], order_by="idx"
|
||||||
|
)
|
||||||
|
current_course_idx = [
|
||||||
|
program_course.idx
|
||||||
|
for program_course in program_courses
|
||||||
|
if program_course.course == course
|
||||||
|
][0]
|
||||||
|
|
||||||
|
for program_course in program_courses:
|
||||||
|
if program_course.idx < current_course_idx:
|
||||||
|
enrollment = frappe.db.get_value(
|
||||||
|
"LMS Enrollment",
|
||||||
|
{"member": frappe.session.user, "course": program_course.course},
|
||||||
|
["name", "progress"],
|
||||||
|
as_dict=1,
|
||||||
|
)
|
||||||
|
if enrollment and enrollment.progress != 100:
|
||||||
|
frappe.throw(
|
||||||
|
_("Please complete the previous courses in the program to enroll in this course.")
|
||||||
|
)
|
||||||
|
elif not enrollment:
|
||||||
|
frappe.throw(
|
||||||
|
_("Please complete the previous courses in the program to enroll in this course.")
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
enrollment = frappe.new_doc("LMS Enrollment")
|
||||||
|
enrollment.update(
|
||||||
|
{
|
||||||
|
"member": frappe.session.user,
|
||||||
|
"course": course,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
enrollment.save()
|
||||||
|
return enrollment
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"app": "lms",
|
||||||
"charts": [
|
"charts": [
|
||||||
{
|
{
|
||||||
"chart_name": "New Signups",
|
"chart_name": "New Signups",
|
||||||
@@ -145,7 +146,7 @@
|
|||||||
"type": "Link"
|
"type": "Link"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2024-08-09 13:19:06.273056",
|
"modified": "2024-11-21 12:16:25.886431",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS",
|
"name": "LMS",
|
||||||
@@ -212,5 +213,6 @@
|
|||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"title": "LMS"
|
"title": "LMS",
|
||||||
}
|
"type": "Workspace"
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: frappe\n"
|
"Project-Id-Version: frappe\n"
|
||||||
"Report-Msgid-Bugs-To: jannat@frappe.io\n"
|
"Report-Msgid-Bugs-To: jannat@frappe.io\n"
|
||||||
"POT-Creation-Date: 2024-11-15 16:04+0000\n"
|
"POT-Creation-Date: 2024-11-15 16:04+0000\n"
|
||||||
"PO-Revision-Date: 2024-11-18 17:32\n"
|
"PO-Revision-Date: 2024-11-23 18:16\n"
|
||||||
"Last-Translator: jannat@frappe.io\n"
|
"Last-Translator: jannat@frappe.io\n"
|
||||||
"Language-Team: Persian\n"
|
"Language-Team: Persian\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@@ -183,7 +183,7 @@ msgstr "آدرس خط 2"
|
|||||||
#: lms/lms/doctype/cohort_web_page/cohort_web_page.json
|
#: lms/lms/doctype/cohort_web_page/cohort_web_page.json
|
||||||
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json
|
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json
|
||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "اَدمین"
|
msgstr "ادمین"
|
||||||
|
|
||||||
#. Name of a role
|
#. Name of a role
|
||||||
#: lms/lms/doctype/lms_badge/lms_badge.json
|
#: lms/lms/doctype/lms_badge/lms_badge.json
|
||||||
@@ -729,11 +729,11 @@ msgstr ""
|
|||||||
|
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:149
|
#: frontend/src/components/Modals/ChapterModal.vue:149
|
||||||
msgid "Chapter added successfully"
|
msgid "Chapter added successfully"
|
||||||
msgstr ""
|
msgstr "فصل با موفقیت اضافه شد"
|
||||||
|
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:193
|
#: frontend/src/components/Modals/ChapterModal.vue:193
|
||||||
msgid "Chapter updated successfully"
|
msgid "Chapter updated successfully"
|
||||||
msgstr ""
|
msgstr "فصل با موفقیت به روز شد"
|
||||||
|
|
||||||
#. Label of the chapters (Table) field in DocType 'LMS Course'
|
#. Label of the chapters (Table) field in DocType 'LMS Course'
|
||||||
#. Group in LMS Course's connections
|
#. Group in LMS Course's connections
|
||||||
@@ -1157,7 +1157,7 @@ msgstr "اسم دوره"
|
|||||||
|
|
||||||
#: frontend/src/pages/CourseDetail.vue:74
|
#: frontend/src/pages/CourseDetail.vue:74
|
||||||
msgid "Course Outline"
|
msgid "Course Outline"
|
||||||
msgstr ""
|
msgstr "طرح کلی دوره"
|
||||||
|
|
||||||
#. Label of the course_price (Currency) field in DocType 'LMS Course'
|
#. Label of the course_price (Currency) field in DocType 'LMS Course'
|
||||||
#: frontend/src/pages/CourseForm.vue:219
|
#: frontend/src/pages/CourseForm.vue:219
|
||||||
@@ -1197,7 +1197,7 @@ msgstr "دوره قبلاً به دسته اضافه شده است."
|
|||||||
|
|
||||||
#: frontend/src/pages/CourseForm.vue:457
|
#: frontend/src/pages/CourseForm.vue:457
|
||||||
msgid "Course deleted successfully"
|
msgid "Course deleted successfully"
|
||||||
msgstr ""
|
msgstr "دوره با موفقیت حذف شد"
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:58
|
#: lms/lms/doctype/lms_batch/lms_batch.py:58
|
||||||
msgid "Course {0} has already been added to this batch."
|
msgid "Course {0} has already been added to this batch."
|
||||||
@@ -1366,19 +1366,19 @@ msgstr "حذف"
|
|||||||
|
|
||||||
#: frontend/src/components/CourseOutline.vue:52
|
#: frontend/src/components/CourseOutline.vue:52
|
||||||
msgid "Delete Chapter"
|
msgid "Delete Chapter"
|
||||||
msgstr ""
|
msgstr "حذف فصل"
|
||||||
|
|
||||||
#: frontend/src/pages/CourseForm.vue:464
|
#: frontend/src/pages/CourseForm.vue:464
|
||||||
msgid "Delete Course"
|
msgid "Delete Course"
|
||||||
msgstr ""
|
msgstr "حذف دوره"
|
||||||
|
|
||||||
#: frontend/src/components/CourseOutline.vue:287
|
#: frontend/src/components/CourseOutline.vue:287
|
||||||
msgid "Delete this chapter?"
|
msgid "Delete this chapter?"
|
||||||
msgstr ""
|
msgstr "این فصل حذف شود؟"
|
||||||
|
|
||||||
#: frontend/src/components/CourseOutline.vue:229
|
#: frontend/src/components/CourseOutline.vue:229
|
||||||
msgid "Delete this lesson?"
|
msgid "Delete this lesson?"
|
||||||
msgstr ""
|
msgstr "این درس حذف شود؟"
|
||||||
|
|
||||||
#: frontend/src/pages/CourseForm.vue:465
|
#: frontend/src/pages/CourseForm.vue:465
|
||||||
msgid "Deleting the course will also delete all its chapters and lessons. Are you sure you want to delete this course?"
|
msgid "Deleting the course will also delete all its chapters and lessons. Are you sure you want to delete this course?"
|
||||||
@@ -1386,11 +1386,11 @@ msgstr ""
|
|||||||
|
|
||||||
#: frontend/src/components/CourseOutline.vue:288
|
#: frontend/src/components/CourseOutline.vue:288
|
||||||
msgid "Deleting this chapter will also delete all its lessons and permanently remove it from the course. This action cannot be undone. Are you sure you want to continue?"
|
msgid "Deleting this chapter will also delete all its lessons and permanently remove it from the course. This action cannot be undone. Are you sure you want to continue?"
|
||||||
msgstr ""
|
msgstr "با حذف این فصل، تمام دروس آن نیز حذف می شود و برای همیشه از دوره حذف می شود. این عمل قابل بازگشت نیست. آیا مطمئن هستید که می خواهید ادامه دهید؟"
|
||||||
|
|
||||||
#: frontend/src/components/CourseOutline.vue:230
|
#: frontend/src/components/CourseOutline.vue:230
|
||||||
msgid "Deleting this lesson will permanently remove it from the course. This action cannot be undone. Are you sure you want to continue?"
|
msgid "Deleting this lesson will permanently remove it from the course. This action cannot be undone. Are you sure you want to continue?"
|
||||||
msgstr ""
|
msgstr "حذف این درس آن را برای همیشه از دوره حذف می کند. این عمل قابل بازگشت نیست. آیا مطمئن هستید که می خواهید ادامه دهید؟"
|
||||||
|
|
||||||
#. Label of the description (Text Editor) field in DocType 'Job Opportunity'
|
#. Label of the description (Text Editor) field in DocType 'Job Opportunity'
|
||||||
#. Label of the description (Small Text) field in DocType 'Certification'
|
#. Label of the description (Small Text) field in DocType 'Certification'
|
||||||
@@ -1763,7 +1763,7 @@ msgstr "رویداد"
|
|||||||
|
|
||||||
#: frontend/src/pages/BatchForm.vue:156
|
#: frontend/src/pages/BatchForm.vue:156
|
||||||
msgid "Example: IST (+5:30)"
|
msgid "Example: IST (+5:30)"
|
||||||
msgstr ""
|
msgstr "مثال: IST (+5:30)"
|
||||||
|
|
||||||
#. Label of the exercise (Link) field in DocType 'Exercise Latest Submission'
|
#. Label of the exercise (Link) field in DocType 'Exercise Latest Submission'
|
||||||
#. Label of the exercise (Link) field in DocType 'Exercise Submission'
|
#. Label of the exercise (Link) field in DocType 'Exercise Submission'
|
||||||
@@ -3287,7 +3287,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:223
|
#: frontend/src/components/Modals/ChapterModal.vue:223
|
||||||
msgid "Only zip files are allowed"
|
msgid "Only zip files are allowed"
|
||||||
msgstr ""
|
msgstr "فقط فایل های zip مجاز هستند"
|
||||||
|
|
||||||
#. Option for the 'Status' (Select) field in DocType 'Job Opportunity'
|
#. Option for the 'Status' (Select) field in DocType 'Job Opportunity'
|
||||||
#. Option for the 'Membership' (Select) field in DocType 'LMS Batch Old'
|
#. Option for the 'Membership' (Select) field in DocType 'LMS Batch Old'
|
||||||
@@ -3551,7 +3551,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: lms/overrides/user.py:240
|
#: lms/overrides/user.py:240
|
||||||
msgid "Please ask your administrator to verify your sign-up"
|
msgid "Please ask your administrator to verify your sign-up"
|
||||||
msgstr "لطفاً از سرپرست خود بخواهید ثبت نام شما را تأیید کند"
|
msgstr "لطفاً از ادمین خود بخواهید ثبت نام شما را تأیید کند"
|
||||||
|
|
||||||
#: lms/overrides/user.py:238
|
#: lms/overrides/user.py:238
|
||||||
msgid "Please check your email for verification"
|
msgid "Please check your email for verification"
|
||||||
@@ -3567,7 +3567,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: frontend/src/components/CourseOutline.vue:312
|
#: frontend/src/components/CourseOutline.vue:312
|
||||||
msgid "Please enroll for this course to view this lesson"
|
msgid "Please enroll for this course to view this lesson"
|
||||||
msgstr ""
|
msgstr "لطفا برای مشاهده این درس در این دوره ثبت نام کنید"
|
||||||
|
|
||||||
#: frontend/src/components/Quiz.vue:13
|
#: frontend/src/components/Quiz.vue:13
|
||||||
msgid "Please ensure that you complete all the questions in {0} minutes."
|
msgid "Please ensure that you complete all the questions in {0} minutes."
|
||||||
@@ -4778,7 +4778,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: frontend/src/pages/SCORMChapter.vue:198
|
#: frontend/src/pages/SCORMChapter.vue:198
|
||||||
msgid "This is a chapter in the course {0}"
|
msgid "This is a chapter in the course {0}"
|
||||||
msgstr ""
|
msgstr "این یک فصل از دوره {0} است"
|
||||||
|
|
||||||
#: lms/lms/widgets/CourseOutline.html:62
|
#: lms/lms/widgets/CourseOutline.html:62
|
||||||
msgid "This lesson is not available for preview. As you are the Instructor of the course only you can see it."
|
msgid "This lesson is not available for preview. As you are the Instructor of the course only you can see it."
|
||||||
@@ -4898,7 +4898,7 @@ msgstr "عنوان"
|
|||||||
|
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:169
|
#: frontend/src/components/Modals/ChapterModal.vue:169
|
||||||
msgid "Title is required"
|
msgid "Title is required"
|
||||||
msgstr ""
|
msgstr "عنوان الزامی است"
|
||||||
|
|
||||||
#. Label of the unavailable_to (Date) field in DocType 'Course Evaluator'
|
#. Label of the unavailable_to (Date) field in DocType 'Course Evaluator'
|
||||||
#: frontend/src/pages/ProfileEvaluator.vue:98
|
#: frontend/src/pages/ProfileEvaluator.vue:98
|
||||||
@@ -5253,11 +5253,11 @@ msgstr ""
|
|||||||
|
|
||||||
#: frontend/src/components/CourseOutline.vue:311
|
#: frontend/src/components/CourseOutline.vue:311
|
||||||
msgid "You are not enrolled"
|
msgid "You are not enrolled"
|
||||||
msgstr ""
|
msgstr "شما ثبت نام نکرده اید"
|
||||||
|
|
||||||
#: frontend/src/pages/SCORMChapter.vue:22
|
#: frontend/src/pages/SCORMChapter.vue:22
|
||||||
msgid "You are not enrolled in this course. Please enroll to access this lesson."
|
msgid "You are not enrolled in this course. Please enroll to access this lesson."
|
||||||
msgstr ""
|
msgstr "شما در این دوره ثبت نام نکرده اید. لطفا برای دسترسی به این دوره ثبت نام کنید."
|
||||||
|
|
||||||
#: frontend/src/pages/Courses.vue:134
|
#: frontend/src/pages/Courses.vue:134
|
||||||
msgid "You can add chapters and lessons to it."
|
msgid "You can add chapters and lessons to it."
|
||||||
@@ -5489,7 +5489,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: lms/lms/doctype/lms_certificate/lms_certificate.py:59
|
#: lms/lms/doctype/lms_certificate/lms_certificate.py:59
|
||||||
msgid "{0} is already certified for the course {1}"
|
msgid "{0} is already certified for the course {1}"
|
||||||
msgstr ""
|
msgstr "{0} قبلاً برای دوره {1} تایید شده است"
|
||||||
|
|
||||||
#: lms/lms/notification/certificate_request_reminder/certificate_request_reminder.html:5
|
#: lms/lms/notification/certificate_request_reminder/certificate_request_reminder.html:5
|
||||||
msgid "{0} is your evaluator"
|
msgid "{0} is your evaluator"
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: Frappe LMS VERSION\n"
|
"Project-Id-Version: Frappe LMS VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: jannat@frappe.io\n"
|
"Report-Msgid-Bugs-To: jannat@frappe.io\n"
|
||||||
"POT-Creation-Date: 2024-11-15 16:04+0000\n"
|
"POT-Creation-Date: 2024-11-22 16:05+0000\n"
|
||||||
"PO-Revision-Date: 2024-11-15 16:04+0000\n"
|
"PO-Revision-Date: 2024-11-22 16:05+0000\n"
|
||||||
"Last-Translator: jannat@frappe.io\n"
|
"Last-Translator: jannat@frappe.io\n"
|
||||||
"Language-Team: jannat@frappe.io\n"
|
"Language-Team: jannat@frappe.io\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@@ -20,6 +20,11 @@ msgstr ""
|
|||||||
msgid " Please evaluate and grade it."
|
msgid " Please evaluate and grade it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/pages/Programs.vue:41
|
||||||
|
#, python-format
|
||||||
|
msgid "% completed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. Paragraph text in the LMS Workspace
|
#. Paragraph text in the LMS Workspace
|
||||||
#: lms/lms/workspace/lms/lms.json
|
#: lms/lms/workspace/lms/lms.json
|
||||||
msgid "<a href=\"/app/lms-settings/LMS%20Settings\">LMS Settings</a>"
|
msgid "<a href=\"/app/lms-settings/LMS%20Settings\">LMS Settings</a>"
|
||||||
@@ -97,7 +102,8 @@ msgstr ""
|
|||||||
#: frontend/src/components/BatchStudents.vue:6
|
#: frontend/src/components/BatchStudents.vue:6
|
||||||
#: frontend/src/components/Categories.vue:26
|
#: frontend/src/components/Categories.vue:26
|
||||||
#: frontend/src/components/LiveClass.vue:11
|
#: frontend/src/components/LiveClass.vue:11
|
||||||
#: frontend/src/components/Members.vue:43
|
#: frontend/src/components/Members.vue:43 frontend/src/pages/ProgramForm.vue:30
|
||||||
|
#: frontend/src/pages/ProgramForm.vue:91 frontend/src/pages/ProgramForm.vue:136
|
||||||
msgid "Add"
|
msgid "Add"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -127,12 +133,20 @@ msgstr ""
|
|||||||
msgid "Add a Student"
|
msgid "Add a Student"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/components/OnboardingBanner.vue:50
|
||||||
|
msgid "Add a chapter"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/components/Modals/BatchCourseModal.vue:5
|
#: frontend/src/components/Modals/BatchCourseModal.vue:5
|
||||||
msgid "Add a course"
|
msgid "Add a course"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/components/OnboardingBanner.vue:73
|
||||||
|
msgid "Add a lesson"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/components/Modals/Question.vue:141
|
#: frontend/src/components/Modals/Question.vue:141
|
||||||
#: frontend/src/pages/QuizForm.vue:181
|
#: frontend/src/pages/QuizForm.vue:182
|
||||||
msgid "Add a new question"
|
msgid "Add a new question"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -148,7 +162,7 @@ msgstr ""
|
|||||||
msgid "Add an existing question"
|
msgid "Add an existing question"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_question/lms_question.py:60
|
#: lms/lms/doctype/lms_question/lms_question.py:66
|
||||||
msgid "Add at least one possible answer for this question: {0}"
|
msgid "Add at least one possible answer for this question: {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -251,6 +265,14 @@ msgstr ""
|
|||||||
msgid "Amount Field"
|
msgid "Amount Field"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lms/lms/doctype/lms_batch/lms_batch.py:70
|
||||||
|
msgid "Amount and currency are required for paid batches."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lms/lms/doctype/lms_course/lms_course.py:57
|
||||||
|
msgid "Amount and currency are required for paid courses."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. Label of the amount_with_gst (Currency) field in DocType 'LMS Payment'
|
#. Label of the amount_with_gst (Currency) field in DocType 'LMS Payment'
|
||||||
#: lms/lms/doctype/lms_payment/lms_payment.json
|
#: lms/lms/doctype/lms_payment/lms_payment.json
|
||||||
msgid "Amount with GST"
|
msgid "Amount with GST"
|
||||||
@@ -344,7 +366,7 @@ msgstr ""
|
|||||||
msgid "Assessment added successfully"
|
msgid "Assessment added successfully"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:75
|
#: lms/lms/doctype/lms_batch/lms_batch.py:80
|
||||||
msgid "Assessment {0} has already been added to this batch."
|
msgid "Assessment {0} has already been added to this batch."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -395,7 +417,7 @@ msgstr ""
|
|||||||
msgid "Assignment will appear at the bottom of the lesson."
|
msgid "Assignment will appear at the bottom of the lesson."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_question/lms_question.py:42
|
#: lms/lms/doctype/lms_question/lms_question.py:43
|
||||||
msgid "At least one option must be correct for this question."
|
msgid "At least one option must be correct for this question."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -538,7 +560,7 @@ msgstr ""
|
|||||||
msgid "Batch Updated"
|
msgid "Batch Updated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:40
|
#: lms/lms/doctype/lms_batch/lms_batch.py:41
|
||||||
msgid "Batch end date cannot be before the batch start date"
|
msgid "Batch end date cannot be before the batch start date"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -725,11 +747,11 @@ msgstr ""
|
|||||||
msgid "Chapter Reference"
|
msgid "Chapter Reference"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:149
|
#: frontend/src/components/Modals/ChapterModal.vue:154
|
||||||
msgid "Chapter added successfully"
|
msgid "Chapter added successfully"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:193
|
#: frontend/src/components/Modals/ChapterModal.vue:198
|
||||||
msgid "Chapter updated successfully"
|
msgid "Chapter updated successfully"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -762,7 +784,7 @@ msgstr ""
|
|||||||
msgid "Choices"
|
msgid "Choices"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/components/Quiz.vue:578 lms/templates/quiz/quiz.html:53
|
#: frontend/src/components/Quiz.vue:581 lms/templates/quiz/quiz.html:53
|
||||||
msgid "Choose all answers that apply"
|
msgid "Choose all answers that apply"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -770,7 +792,7 @@ msgstr ""
|
|||||||
msgid "Choose an icon"
|
msgid "Choose an icon"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/components/Quiz.vue:579 lms/templates/quiz/quiz.html:53
|
#: frontend/src/components/Quiz.vue:582 lms/templates/quiz/quiz.html:53
|
||||||
msgid "Choose one answer"
|
msgid "Choose one answer"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -986,7 +1008,7 @@ msgid "Contact the Administrator to enroll for this course."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. Label of the content (Text) field in DocType 'Course Lesson'
|
#. Label of the content (Text) field in DocType 'Course Lesson'
|
||||||
#: frontend/src/pages/LessonForm.vue:58
|
#: frontend/src/pages/LessonForm.vue:62
|
||||||
#: lms/lms/doctype/course_lesson/course_lesson.json
|
#: lms/lms/doctype/course_lesson/course_lesson.json
|
||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1055,6 +1077,7 @@ msgstr ""
|
|||||||
#. Label of the course (Link) field in DocType 'LMS Enrollment'
|
#. Label of the course (Link) field in DocType 'LMS Enrollment'
|
||||||
#. Label of the course (Link) field in DocType 'LMS Exercise'
|
#. Label of the course (Link) field in DocType 'LMS Exercise'
|
||||||
#. Label of the course (Link) field in DocType 'LMS Mentor Request'
|
#. Label of the course (Link) field in DocType 'LMS Mentor Request'
|
||||||
|
#. Label of the course (Link) field in DocType 'LMS Program Course'
|
||||||
#. Label of the course (Link) field in DocType 'LMS Quiz'
|
#. Label of the course (Link) field in DocType 'LMS Quiz'
|
||||||
#. Label of the course (Link) field in DocType 'LMS Quiz Submission'
|
#. Label of the course (Link) field in DocType 'LMS Quiz Submission'
|
||||||
#. Label of the course (Link) field in DocType 'Related Courses'
|
#. Label of the course (Link) field in DocType 'Related Courses'
|
||||||
@@ -1084,6 +1107,7 @@ msgstr ""
|
|||||||
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json
|
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json
|
||||||
#: lms/lms/doctype/lms_exercise/lms_exercise.json
|
#: lms/lms/doctype/lms_exercise/lms_exercise.json
|
||||||
#: lms/lms/doctype/lms_mentor_request/lms_mentor_request.json
|
#: lms/lms/doctype/lms_mentor_request/lms_mentor_request.json
|
||||||
|
#: lms/lms/doctype/lms_program_course/lms_program_course.json
|
||||||
#: lms/lms/doctype/lms_quiz/lms_quiz.json
|
#: lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||||
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json
|
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json
|
||||||
#: lms/lms/doctype/related_courses/related_courses.json
|
#: lms/lms/doctype/related_courses/related_courses.json
|
||||||
@@ -1112,6 +1136,7 @@ msgstr ""
|
|||||||
#. Name of a role
|
#. Name of a role
|
||||||
#: frontend/src/pages/ProfileRoles.vue:16
|
#: frontend/src/pages/ProfileRoles.vue:16
|
||||||
#: lms/lms/doctype/lms_course/lms_course.json
|
#: lms/lms/doctype/lms_course/lms_course.json
|
||||||
|
#: lms/lms/doctype/lms_program/lms_program.json
|
||||||
#: lms/lms/doctype/lms_question/lms_question.json
|
#: lms/lms/doctype/lms_question/lms_question.json
|
||||||
#: lms/lms/doctype/lms_quiz/lms_quiz.json
|
#: lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||||
msgid "Course Creator"
|
msgid "Course Creator"
|
||||||
@@ -1182,22 +1207,33 @@ msgstr ""
|
|||||||
#. Label of the course_title (Data) field in DocType 'Course Chapter'
|
#. Label of the course_title (Data) field in DocType 'Course Chapter'
|
||||||
#. Label of the course_title (Data) field in DocType 'LMS Certificate'
|
#. Label of the course_title (Data) field in DocType 'LMS Certificate'
|
||||||
#. Label of the course_title (Data) field in DocType 'LMS Certificate Request'
|
#. Label of the course_title (Data) field in DocType 'LMS Certificate Request'
|
||||||
|
#. Label of the course_title (Data) field in DocType 'LMS Program Course'
|
||||||
#: lms/lms/doctype/batch_course/batch_course.json
|
#: lms/lms/doctype/batch_course/batch_course.json
|
||||||
#: lms/lms/doctype/course_chapter/course_chapter.json
|
#: lms/lms/doctype/course_chapter/course_chapter.json
|
||||||
#: lms/lms/doctype/lms_certificate/lms_certificate.json
|
#: lms/lms/doctype/lms_certificate/lms_certificate.json
|
||||||
#: lms/lms/doctype/lms_certificate_request/lms_certificate_request.json
|
#: lms/lms/doctype/lms_certificate_request/lms_certificate_request.json
|
||||||
|
#: lms/lms/doctype/lms_program_course/lms_program_course.json
|
||||||
msgid "Course Title"
|
msgid "Course Title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:340
|
#: frontend/src/pages/ProgramForm.vue:226
|
||||||
|
msgid "Course added to program"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lms/lms/doctype/lms_batch/lms_batch.py:345
|
||||||
msgid "Course already added to the batch."
|
msgid "Course already added to the batch."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/CourseForm.vue:457
|
#: frontend/src/pages/CourseForm.vue:460
|
||||||
msgid "Course deleted successfully"
|
msgid "Course deleted successfully"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:58
|
#: frontend/src/pages/ProgramForm.vue:295
|
||||||
|
msgid "Course moved successfully"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lms/lms/doctype/lms_batch/lms_batch.py:59
|
||||||
|
#: lms/lms/doctype/lms_program/lms_program.py:19
|
||||||
msgid "Course {0} has already been added to this batch."
|
msgid "Course {0} has already been added to this batch."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1232,6 +1268,7 @@ msgid "Cover Image"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:9
|
#: frontend/src/components/Modals/ChapterModal.vue:9
|
||||||
|
#: frontend/src/pages/Programs.vue:99
|
||||||
msgid "Create"
|
msgid "Create"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1247,7 +1284,7 @@ msgstr ""
|
|||||||
msgid "Create a Batch"
|
msgid "Create a Batch"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/Courses.vue:131 lms/templates/onboarding_header.html:19
|
#: frontend/src/pages/Courses.vue:132 lms/templates/onboarding_header.html:19
|
||||||
msgid "Create a Course"
|
msgid "Create a Course"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1255,6 +1292,10 @@ msgstr ""
|
|||||||
msgid "Create a Live Class"
|
msgid "Create a Live Class"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/components/OnboardingBanner.vue:27
|
||||||
|
msgid "Create a course"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/components/Modals/Question.vue:31
|
#: frontend/src/components/Modals/Question.vue:31
|
||||||
msgid "Create a new question"
|
msgid "Create a new question"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1358,7 +1399,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: frontend/src/components/CourseOutline.vue:235
|
#: frontend/src/components/CourseOutline.vue:235
|
||||||
#: frontend/src/components/CourseOutline.vue:293
|
#: frontend/src/components/CourseOutline.vue:293
|
||||||
#: frontend/src/pages/CourseForm.vue:15 frontend/src/pages/CourseForm.vue:470
|
#: frontend/src/pages/CourseForm.vue:15 frontend/src/pages/CourseForm.vue:473
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1366,7 +1407,7 @@ msgstr ""
|
|||||||
msgid "Delete Chapter"
|
msgid "Delete Chapter"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/CourseForm.vue:464
|
#: frontend/src/pages/CourseForm.vue:467
|
||||||
msgid "Delete Course"
|
msgid "Delete Course"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1378,7 +1419,7 @@ msgstr ""
|
|||||||
msgid "Delete this lesson?"
|
msgid "Delete this lesson?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/CourseForm.vue:465
|
#: frontend/src/pages/CourseForm.vue:468
|
||||||
msgid "Deleting the course will also delete all its chapters and lessons. Are you sure you want to delete this course?"
|
msgid "Deleting the course will also delete all its chapters and lessons. Are you sure you want to delete this course?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1468,7 +1509,7 @@ msgstr ""
|
|||||||
msgid "Dream Companies"
|
msgid "Dream Companies"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_question/lms_question.py:32
|
#: lms/lms/doctype/lms_question/lms_question.py:33
|
||||||
msgid "Duplicate options found for this question."
|
msgid "Duplicate options found for this question."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1506,7 +1547,7 @@ msgstr ""
|
|||||||
#: frontend/src/components/CourseCardOverlay.vue:86
|
#: frontend/src/components/CourseCardOverlay.vue:86
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:9
|
#: frontend/src/components/Modals/ChapterModal.vue:9
|
||||||
#: frontend/src/pages/JobDetail.vue:31 frontend/src/pages/Lesson.vue:65
|
#: frontend/src/pages/JobDetail.vue:31 frontend/src/pages/Lesson.vue:65
|
||||||
#: frontend/src/pages/Profile.vue:32
|
#: frontend/src/pages/Profile.vue:32 frontend/src/pages/Programs.vue:55
|
||||||
msgid "Edit"
|
msgid "Edit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1519,7 +1560,7 @@ msgstr ""
|
|||||||
msgid "Edit Profile"
|
msgid "Edit Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/QuizForm.vue:180
|
#: frontend/src/pages/QuizForm.vue:181
|
||||||
msgid "Edit the question"
|
msgid "Edit the question"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1580,6 +1621,15 @@ msgstr ""
|
|||||||
msgid "Enable Google API in Google Settings to send calendar invites for evaluations."
|
msgid "Enable Google API in Google Settings to send calendar invites for evaluations."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. Label of the enable_learning_paths (Check) field in DocType 'LMS Settings'
|
||||||
|
#: lms/lms/doctype/lms_settings/lms_settings.json
|
||||||
|
msgid "Enable Learning Paths"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/components/Modals/ChapterModal.vue:24
|
||||||
|
msgid "Enable this only if you want to upload a SCORM package as a chapter."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. Label of the enabled (Check) field in DocType 'LMS Badge'
|
#. Label of the enabled (Check) field in DocType 'LMS Badge'
|
||||||
#: lms/lms/doctype/lms_badge/lms_badge.json
|
#: lms/lms/doctype/lms_badge/lms_badge.json
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
@@ -1632,7 +1682,7 @@ msgstr ""
|
|||||||
msgid "Enrolled successfully"
|
msgid "Enrolled successfully"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:98
|
#: lms/lms/doctype/lms_batch/lms_batch.py:103
|
||||||
msgid "Enrollment Confirmation for the Next Training Batch"
|
msgid "Enrollment Confirmation for the Next Training Batch"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1641,7 +1691,7 @@ msgstr ""
|
|||||||
msgid "Enrollment Count"
|
msgid "Enrollment Count"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/utils.py:1702
|
#: lms/lms/utils.py:1705
|
||||||
msgid "Enrollment Failed"
|
msgid "Enrollment Failed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1670,14 +1720,14 @@ msgid "Enter the correct answer"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/components/Modals/AnnouncementModal.vue:105
|
#: frontend/src/components/Modals/AnnouncementModal.vue:105
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:154
|
#: frontend/src/components/Modals/ChapterModal.vue:159
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:161
|
#: frontend/src/components/Modals/ChapterModal.vue:166
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:197
|
#: frontend/src/components/Modals/ChapterModal.vue:202
|
||||||
#: frontend/src/components/Modals/Question.vue:246
|
#: frontend/src/components/Modals/Question.vue:246
|
||||||
#: frontend/src/components/Modals/Question.vue:266
|
#: frontend/src/components/Modals/Question.vue:266
|
||||||
#: frontend/src/components/Modals/Question.vue:323
|
#: frontend/src/components/Modals/Question.vue:323
|
||||||
#: frontend/src/pages/Billing.vue:264 frontend/src/pages/QuizForm.vue:349
|
#: frontend/src/pages/Billing.vue:264 frontend/src/pages/QuizForm.vue:350
|
||||||
#: frontend/src/pages/QuizForm.vue:364
|
#: frontend/src/pages/QuizForm.vue:365
|
||||||
#: frontend/src/pages/QuizSubmission.vue:117
|
#: frontend/src/pages/QuizSubmission.vue:117
|
||||||
msgid "Error"
|
msgid "Error"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1706,7 +1756,7 @@ msgstr ""
|
|||||||
msgid "Evaluation Request"
|
msgid "Evaluation Request"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:82
|
#: lms/lms/doctype/lms_batch/lms_batch.py:87
|
||||||
msgid "Evaluation end date cannot be less than the batch end date."
|
msgid "Evaluation end date cannot be less than the batch end date."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1872,7 +1922,7 @@ msgstr ""
|
|||||||
msgid "Flexible Time"
|
msgid "Flexible Time"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/QuizForm.vue:462
|
#: frontend/src/pages/QuizForm.vue:463
|
||||||
msgid "Form to create and edit quizzes"
|
msgid "Form to create and edit quizzes"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1920,7 +1970,9 @@ msgid "From Date"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. Label of the full_name (Data) field in DocType 'Invite Request'
|
#. Label of the full_name (Data) field in DocType 'Invite Request'
|
||||||
|
#. Label of the full_name (Data) field in DocType 'LMS Program Member'
|
||||||
#: lms/lms/doctype/invite_request/invite_request.json
|
#: lms/lms/doctype/invite_request/invite_request.json
|
||||||
|
#: lms/lms/doctype/lms_program_member/lms_program_member.json
|
||||||
#: lms/templates/signup-form.html:5
|
#: lms/templates/signup-form.html:5
|
||||||
msgid "Full Name"
|
msgid "Full Name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1952,6 +2004,11 @@ msgstr ""
|
|||||||
msgid "GSTIN"
|
msgid "GSTIN"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. Label of the general_tab (Tab Break) field in DocType 'LMS Settings'
|
||||||
|
#: lms/lms/doctype/lms_settings/lms_settings.json
|
||||||
|
msgid "General"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_certificate_request/lms_certificate_request.js:18
|
#: lms/lms/doctype/lms_certificate_request/lms_certificate_request.js:18
|
||||||
msgid "Generate Google Meet Link"
|
msgid "Generate Google Meet Link"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -2083,7 +2140,7 @@ msgstr ""
|
|||||||
msgid "I am unavailable"
|
msgid "I am unavailable"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/QuizForm.vue:383
|
#: frontend/src/pages/QuizForm.vue:384
|
||||||
msgid "ID"
|
msgid "ID"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -2224,7 +2281,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. Label of the instructor_notes (Markdown Editor) field in DocType 'Course
|
#. Label of the instructor_notes (Markdown Editor) field in DocType 'Course
|
||||||
#. Lesson'
|
#. Lesson'
|
||||||
#: frontend/src/pages/Lesson.vue:128 frontend/src/pages/LessonForm.vue:38
|
#: frontend/src/pages/Lesson.vue:128 frontend/src/pages/LessonForm.vue:42
|
||||||
#: lms/lms/doctype/course_lesson/course_lesson.json
|
#: lms/lms/doctype/course_lesson/course_lesson.json
|
||||||
msgid "Instructor Notes"
|
msgid "Instructor Notes"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -2300,7 +2357,6 @@ msgstr ""
|
|||||||
|
|
||||||
#. Label of the is_scorm_package (Check) field in DocType 'Course Chapter'
|
#. Label of the is_scorm_package (Check) field in DocType 'Course Chapter'
|
||||||
#. Label of the is_scorm_package (Check) field in DocType 'Course Lesson'
|
#. Label of the is_scorm_package (Check) field in DocType 'Course Lesson'
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:26
|
|
||||||
#: lms/lms/doctype/course_chapter/course_chapter.json
|
#: lms/lms/doctype/course_chapter/course_chapter.json
|
||||||
#: lms/lms/doctype/course_lesson/course_lesson.json
|
#: lms/lms/doctype/course_lesson/course_lesson.json
|
||||||
msgid "Is SCORM Package"
|
msgid "Is SCORM Package"
|
||||||
@@ -2330,6 +2386,10 @@ msgstr ""
|
|||||||
msgid "Items in Sidebar"
|
msgid "Items in Sidebar"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/pages/ProgramForm.vue:269
|
||||||
|
msgid "Items removed successfully"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: lms/templates/signup-form.html:6
|
#: lms/templates/signup-form.html:6
|
||||||
msgid "Jane Doe"
|
msgid "Jane Doe"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -2529,6 +2589,21 @@ msgstr ""
|
|||||||
msgid "LMS Payment"
|
msgid "LMS Payment"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. Name of a DocType
|
||||||
|
#: lms/lms/doctype/lms_program/lms_program.json
|
||||||
|
msgid "LMS Program"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Name of a DocType
|
||||||
|
#: lms/lms/doctype/lms_program_course/lms_program_course.json
|
||||||
|
msgid "LMS Program Course"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Name of a DocType
|
||||||
|
#: lms/lms/doctype/lms_program_member/lms_program_member.json
|
||||||
|
msgid "LMS Program Member"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. Name of a DocType
|
#. Name of a DocType
|
||||||
#: lms/lms/doctype/lms_question/lms_question.json
|
#: lms/lms/doctype/lms_question/lms_question.json
|
||||||
msgid "LMS Question"
|
msgid "LMS Question"
|
||||||
@@ -2588,6 +2663,7 @@ msgstr ""
|
|||||||
#: lms/lms/doctype/lms_live_class/lms_live_class.json
|
#: lms/lms/doctype/lms_live_class/lms_live_class.json
|
||||||
#: lms/lms/doctype/lms_quiz/lms_quiz.json
|
#: lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||||
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json
|
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json
|
||||||
|
#: lms/lms/doctype/lms_settings/lms_settings.json
|
||||||
#: lms/lms/doctype/lms_source/lms_source.json
|
#: lms/lms/doctype/lms_source/lms_source.json
|
||||||
#: lms/lms/doctype/user_skill/user_skill.json
|
#: lms/lms/doctype/user_skill/user_skill.json
|
||||||
msgid "LMS Student"
|
msgid "LMS Student"
|
||||||
@@ -2810,7 +2886,7 @@ msgstr ""
|
|||||||
#. Label of the marks (Int) field in DocType 'LMS Quiz Result'
|
#. Label of the marks (Int) field in DocType 'LMS Quiz Result'
|
||||||
#: frontend/src/components/Modals/Question.vue:50
|
#: frontend/src/components/Modals/Question.vue:50
|
||||||
#: frontend/src/components/Modals/Question.vue:96
|
#: frontend/src/components/Modals/Question.vue:96
|
||||||
#: frontend/src/components/Quiz.vue:94 frontend/src/pages/QuizForm.vue:393
|
#: frontend/src/components/Quiz.vue:94 frontend/src/pages/QuizForm.vue:394
|
||||||
#: frontend/src/pages/QuizSubmission.vue:52
|
#: frontend/src/pages/QuizSubmission.vue:52
|
||||||
#: lms/lms/doctype/lms_quiz_question/lms_quiz_question.json
|
#: lms/lms/doctype/lms_quiz_question/lms_quiz_question.json
|
||||||
#: lms/lms/doctype/lms_quiz_result/lms_quiz_result.json
|
#: lms/lms/doctype/lms_quiz_result/lms_quiz_result.json
|
||||||
@@ -2865,6 +2941,7 @@ msgstr ""
|
|||||||
#. Option for the 'Role' (Select) field in DocType 'LMS Enrollment'
|
#. Option for the 'Role' (Select) field in DocType 'LMS Enrollment'
|
||||||
#. Label of the member (Link) field in DocType 'LMS Mentor Request'
|
#. Label of the member (Link) field in DocType 'LMS Mentor Request'
|
||||||
#. Label of the member (Link) field in DocType 'LMS Payment'
|
#. 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'
|
#. Label of the member (Link) field in DocType 'LMS Quiz Submission'
|
||||||
#: frontend/src/pages/QuizSubmission.vue:27
|
#: frontend/src/pages/QuizSubmission.vue:27
|
||||||
#: frontend/src/pages/QuizSubmissionList.vue:77
|
#: frontend/src/pages/QuizSubmissionList.vue:77
|
||||||
@@ -2879,6 +2956,7 @@ msgstr ""
|
|||||||
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json
|
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json
|
||||||
#: lms/lms/doctype/lms_mentor_request/lms_mentor_request.json
|
#: lms/lms/doctype/lms_mentor_request/lms_mentor_request.json
|
||||||
#: lms/lms/doctype/lms_payment/lms_payment.json
|
#: lms/lms/doctype/lms_payment/lms_payment.json
|
||||||
|
#: lms/lms/doctype/lms_program_member/lms_program_member.json
|
||||||
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json
|
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json
|
||||||
#: lms/lms/report/course_progress_summary/course_progress_summary.py:64
|
#: lms/lms/report/course_progress_summary/course_progress_summary.py:64
|
||||||
msgid "Member"
|
msgid "Member"
|
||||||
@@ -2928,6 +3006,14 @@ msgstr ""
|
|||||||
msgid "Member Type"
|
msgid "Member Type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/pages/ProgramForm.vue:248
|
||||||
|
msgid "Member added to program"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lms/lms/doctype/lms_program/lms_program.py:29
|
||||||
|
msgid "Member {0} has already been added to this batch."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. Group in LMS Batch Old's connections
|
#. Group in LMS Batch Old's connections
|
||||||
#: lms/lms/doctype/lms_batch_old/lms_batch_old.json
|
#: lms/lms/doctype/lms_batch_old/lms_batch_old.json
|
||||||
msgid "Members"
|
msgid "Members"
|
||||||
@@ -3000,6 +3086,10 @@ msgstr ""
|
|||||||
msgid "Milestones"
|
msgid "Milestones"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lms/lms/doctype/lms_question/lms_question.py:48
|
||||||
|
msgid "Minimum two options are required for multiple choice questions."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. Name of a role
|
#. Name of a role
|
||||||
#: frontend/src/pages/ProfileRoles.vue:10
|
#: frontend/src/pages/ProfileRoles.vue:10
|
||||||
#: lms/lms/doctype/course_evaluator/course_evaluator.json
|
#: lms/lms/doctype/course_evaluator/course_evaluator.json
|
||||||
@@ -3011,6 +3101,7 @@ msgstr ""
|
|||||||
#: lms/lms/doctype/lms_certificate_request/lms_certificate_request.json
|
#: lms/lms/doctype/lms_certificate_request/lms_certificate_request.json
|
||||||
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json
|
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json
|
||||||
#: lms/lms/doctype/lms_live_class/lms_live_class.json
|
#: lms/lms/doctype/lms_live_class/lms_live_class.json
|
||||||
|
#: lms/lms/doctype/lms_program/lms_program.json
|
||||||
#: lms/lms/doctype/lms_question/lms_question.json
|
#: lms/lms/doctype/lms_question/lms_question.json
|
||||||
#: lms/lms/doctype/lms_quiz/lms_quiz.json
|
#: lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||||
#: lms/lms/doctype/lms_source/lms_source.json
|
#: lms/lms/doctype/lms_source/lms_source.json
|
||||||
@@ -3055,8 +3146,8 @@ msgid "My calendar"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. Option for the 'Event' (Select) field in DocType 'LMS Badge'
|
#. Option for the 'Event' (Select) field in DocType 'LMS Badge'
|
||||||
#: frontend/src/pages/Batches.vue:30 frontend/src/pages/Courses.vue:44
|
#: frontend/src/pages/Batches.vue:30 frontend/src/pages/Courses.vue:45
|
||||||
#: lms/lms/doctype/lms_badge/lms_badge.json
|
#: frontend/src/pages/Programs.vue:14 lms/lms/doctype/lms_badge/lms_badge.json
|
||||||
msgid "New"
|
msgid "New"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -3080,11 +3171,23 @@ msgstr ""
|
|||||||
msgid "New Job Applicant"
|
msgid "New Job Applicant"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/pages/Programs.vue:96
|
||||||
|
msgid "New Program"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/pages/ProgramForm.vue:132
|
||||||
|
msgid "New Program Course"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/pages/ProgramForm.vue:133
|
||||||
|
msgid "New Program Member"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/QuizForm.vue:122
|
#: frontend/src/pages/QuizForm.vue:122
|
||||||
msgid "New Question"
|
msgid "New Question"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/QuizForm.vue:453 frontend/src/pages/QuizForm.vue:461
|
#: frontend/src/pages/QuizForm.vue:454 frontend/src/pages/QuizForm.vue:462
|
||||||
#: frontend/src/pages/Quizzes.vue:18
|
#: frontend/src/pages/Quizzes.vue:18
|
||||||
msgid "New Quiz"
|
msgid "New Quiz"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -3147,10 +3250,14 @@ msgstr ""
|
|||||||
msgid "No courses created"
|
msgid "No courses created"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/Courses.vue:146
|
#: frontend/src/pages/Courses.vue:147
|
||||||
msgid "No courses found"
|
msgid "No courses found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/pages/Programs.vue:72
|
||||||
|
msgid "No courses in this program"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: lms/templates/courses_under_review.html:14
|
#: lms/templates/courses_under_review.html:14
|
||||||
msgid "No courses under review"
|
msgid "No courses under review"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -3167,6 +3274,10 @@ msgstr ""
|
|||||||
msgid "No live classes scheduled"
|
msgid "No live classes scheduled"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/pages/Programs.vue:82
|
||||||
|
msgid "No programs found"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/Quizzes.vue:56
|
#: frontend/src/pages/Quizzes.vue:56
|
||||||
msgid "No quizzes found"
|
msgid "No quizzes found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -3187,7 +3298,7 @@ msgstr ""
|
|||||||
msgid "No {0} batches"
|
msgid "No {0} batches"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/Courses.vue:106
|
#: frontend/src/pages/Courses.vue:107
|
||||||
msgid "No {0} courses"
|
msgid "No {0} courses"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -3275,15 +3386,19 @@ msgstr ""
|
|||||||
msgid "Online"
|
msgid "Online"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/pages/ProgramForm.vue:156
|
||||||
|
msgid "Only courses for which self learning is disabled can be added to program."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: lms/templates/assignment.html:6
|
#: lms/templates/assignment.html:6
|
||||||
msgid "Only files of type {0} will be accepted."
|
msgid "Only files of type {0} will be accepted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/CourseForm.vue:494 frontend/src/utils/index.js:518
|
#: frontend/src/pages/CourseForm.vue:497 frontend/src/utils/index.js:518
|
||||||
msgid "Only image file is allowed."
|
msgid "Only image file is allowed."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:223
|
#: frontend/src/components/Modals/ChapterModal.vue:220
|
||||||
msgid "Only zip files are allowed"
|
msgid "Only zip files are allowed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -3559,7 +3674,11 @@ msgstr ""
|
|||||||
msgid "Please click on the following button to set your new password"
|
msgid "Please click on the following button to set your new password"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:251
|
#: lms/lms/utils.py:1817 lms/lms/utils.py:1821
|
||||||
|
msgid "Please complete the previous courses in the program to enroll in this course."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lms/lms/doctype/lms_batch/lms_batch.py:256
|
||||||
msgid "Please enable Zoom Settings to use this feature."
|
msgid "Please enable Zoom Settings to use this feature."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -3571,11 +3690,19 @@ msgstr ""
|
|||||||
msgid "Please ensure that you complete all the questions in {0} minutes."
|
msgid "Please ensure that you complete all the questions in {0} minutes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/components/Modals/LiveClassModal.vue:164
|
||||||
|
msgid "Please enter a title."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.py:38
|
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.py:38
|
||||||
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.py:98
|
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.py:98
|
||||||
msgid "Please enter a valid URL."
|
msgid "Please enter a valid URL."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/components/Modals/LiveClassModal.vue:176
|
||||||
|
msgid "Please enter a valid time in the format HH:mm."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.py:92
|
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.py:92
|
||||||
msgid "Please enter the URL for assignment submission."
|
msgid "Please enter the URL for assignment submission."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -3584,11 +3711,11 @@ msgstr ""
|
|||||||
msgid "Please enter your answer"
|
msgid "Please enter your answer"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:65
|
#: lms/lms/doctype/lms_batch/lms_batch.py:66
|
||||||
msgid "Please install the Payments app to create a paid batches."
|
msgid "Please install the Payments app to create a paid batches."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_course/lms_course.py:52
|
#: lms/lms/doctype/lms_course/lms_course.py:53
|
||||||
msgid "Please install the Payments app to create a paid courses."
|
msgid "Please install the Payments app to create a paid courses."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -3613,11 +3740,31 @@ msgstr ""
|
|||||||
msgid "Please prepare well and be on time for the evaluations."
|
msgid "Please prepare well and be on time for the evaluations."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/components/Modals/LiveClassModal.vue:167
|
||||||
|
msgid "Please select a date."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/components/Modals/LiveClassModal.vue:191
|
||||||
|
msgid "Please select a duration."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/components/Modals/LiveClassModal.vue:188
|
||||||
|
msgid "Please select a future date and time."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/components/Modals/LiveClassModal.vue:170
|
||||||
|
msgid "Please select a time."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/components/Modals/LiveClassModal.vue:173
|
||||||
|
msgid "Please select a timezone."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: lms/templates/emails/job_report.html:6
|
#: lms/templates/emails/job_report.html:6
|
||||||
msgid "Please take appropriate action at {0}"
|
msgid "Please take appropriate action at {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:172
|
#: frontend/src/components/Modals/ChapterModal.vue:177
|
||||||
msgid "Please upload a SCORM package"
|
msgid "Please upload a SCORM package"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -3754,8 +3901,30 @@ msgstr ""
|
|||||||
msgid "Profile Image"
|
msgid "Profile Image"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/pages/ProgramForm.vue:154
|
||||||
|
msgid "Program Course"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Label of the program_courses (Table) field in DocType 'LMS Program'
|
||||||
|
#: frontend/src/pages/ProgramForm.vue:17
|
||||||
|
#: lms/lms/doctype/lms_program/lms_program.json
|
||||||
|
msgid "Program Courses"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/pages/ProgramForm.vue:169
|
||||||
|
msgid "Program Member"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. Label of the program_members (Table) field in DocType 'LMS Program'
|
||||||
|
#: frontend/src/pages/ProgramForm.vue:78
|
||||||
|
#: lms/lms/doctype/lms_program/lms_program.json
|
||||||
|
msgid "Program Members"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. Label of the progress (Float) field in DocType 'LMS Enrollment'
|
#. Label of the progress (Float) field in DocType 'LMS Enrollment'
|
||||||
|
#. Label of the progress (Int) field in DocType 'LMS Program Member'
|
||||||
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json
|
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json
|
||||||
|
#: lms/lms/doctype/lms_program_member/lms_program_member.json
|
||||||
msgid "Progress"
|
msgid "Progress"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -3805,7 +3974,7 @@ msgstr ""
|
|||||||
#. Label of the question (Text) field in DocType 'LMS Quiz Result'
|
#. Label of the question (Text) field in DocType 'LMS Quiz Result'
|
||||||
#: frontend/src/components/Modals/Question.vue:38
|
#: frontend/src/components/Modals/Question.vue:38
|
||||||
#: frontend/src/pages/AssignmentSubmission.vue:26
|
#: frontend/src/pages/AssignmentSubmission.vue:26
|
||||||
#: frontend/src/pages/QuizForm.vue:388
|
#: frontend/src/pages/QuizForm.vue:389
|
||||||
#: lms/lms/doctype/course_lesson/course_lesson.json
|
#: lms/lms/doctype/course_lesson/course_lesson.json
|
||||||
#: lms/lms/doctype/lms_assignment/lms_assignment.json
|
#: lms/lms/doctype/lms_assignment/lms_assignment.json
|
||||||
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json
|
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json
|
||||||
@@ -3851,7 +4020,7 @@ msgstr ""
|
|||||||
msgid "Questions"
|
msgid "Questions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/QuizForm.vue:430
|
#: frontend/src/pages/QuizForm.vue:431
|
||||||
msgid "Questions deleted successfully"
|
msgid "Questions deleted successfully"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -3889,7 +4058,7 @@ msgstr ""
|
|||||||
msgid "Quiz Title"
|
msgid "Quiz Title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/QuizForm.vue:342
|
#: frontend/src/pages/QuizForm.vue:343
|
||||||
msgid "Quiz created successfully"
|
msgid "Quiz created successfully"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -3897,7 +4066,7 @@ msgstr ""
|
|||||||
msgid "Quiz is not available to Guest users. Please login to continue."
|
msgid "Quiz is not available to Guest users. Please login to continue."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/QuizForm.vue:361
|
#: frontend/src/pages/QuizForm.vue:362
|
||||||
msgid "Quiz updated successfully"
|
msgid "Quiz updated successfully"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -3906,7 +4075,7 @@ msgstr ""
|
|||||||
msgid "Quiz will appear at the bottom of the lesson."
|
msgid "Quiz will appear at the bottom of the lesson."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/QuizForm.vue:441 frontend/src/pages/Quizzes.vue:136
|
#: frontend/src/pages/QuizForm.vue:442 frontend/src/pages/Quizzes.vue:136
|
||||||
#: frontend/src/pages/Quizzes.vue:146
|
#: frontend/src/pages/Quizzes.vue:146
|
||||||
msgid "Quizzes"
|
msgid "Quizzes"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -4063,19 +4232,19 @@ msgstr ""
|
|||||||
msgid "Route"
|
msgid "Route"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:194
|
#: lms/lms/doctype/lms_batch/lms_batch.py:199
|
||||||
msgid "Row #{0} Date cannot be outside the batch duration."
|
msgid "Row #{0} Date cannot be outside the batch duration."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:189
|
#: lms/lms/doctype/lms_batch/lms_batch.py:194
|
||||||
msgid "Row #{0} End time cannot be outside the batch duration."
|
msgid "Row #{0} End time cannot be outside the batch duration."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:171
|
#: lms/lms/doctype/lms_batch/lms_batch.py:176
|
||||||
msgid "Row #{0} Start time cannot be greater than or equal to end time."
|
msgid "Row #{0} Start time cannot be greater than or equal to end time."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:180
|
#: lms/lms/doctype/lms_batch/lms_batch.py:185
|
||||||
msgid "Row #{0} Start time cannot be outside the batch duration."
|
msgid "Row #{0} Start time cannot be outside the batch duration."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -4093,6 +4262,7 @@ msgid "SCORM"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. Label of the scorm_package (Link) field in DocType 'Course Chapter'
|
#. Label of the scorm_package (Link) field in DocType 'Course Chapter'
|
||||||
|
#: frontend/src/components/Modals/ChapterModal.vue:22
|
||||||
#: lms/lms/doctype/course_chapter/course_chapter.json
|
#: lms/lms/doctype/course_chapter/course_chapter.json
|
||||||
msgid "SCORM Package"
|
msgid "SCORM Package"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -4115,8 +4285,9 @@ msgstr ""
|
|||||||
#: frontend/src/components/QuizPlugin.vue:23
|
#: frontend/src/components/QuizPlugin.vue:23
|
||||||
#: frontend/src/pages/AssignmentSubmission.vue:7
|
#: frontend/src/pages/AssignmentSubmission.vue:7
|
||||||
#: frontend/src/pages/BatchForm.vue:8 frontend/src/pages/CourseForm.vue:20
|
#: frontend/src/pages/BatchForm.vue:8 frontend/src/pages/CourseForm.vue:20
|
||||||
#: frontend/src/pages/JobCreation.vue:8 frontend/src/pages/LessonForm.vue:10
|
#: frontend/src/pages/JobCreation.vue:8 frontend/src/pages/LessonForm.vue:14
|
||||||
#: frontend/src/pages/QuizForm.vue:34 frontend/src/pages/QuizSubmission.vue:14
|
#: frontend/src/pages/ProgramForm.vue:7 frontend/src/pages/QuizForm.vue:34
|
||||||
|
#: frontend/src/pages/QuizSubmission.vue:14
|
||||||
#: lms/public/js/common_functions.js:405
|
#: lms/public/js/common_functions.js:405
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -4332,6 +4503,10 @@ msgstr ""
|
|||||||
msgid "Skip"
|
msgid "Skip"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/components/OnboardingBanner.vue:3
|
||||||
|
msgid "Skip Onboarding"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/course_evaluator/course_evaluator.py:57
|
#: lms/lms/doctype/course_evaluator/course_evaluator.py:57
|
||||||
msgid "Slot Times are overlapping for some schedules."
|
msgid "Slot Times are overlapping for some schedules."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -4505,7 +4680,7 @@ msgstr ""
|
|||||||
msgid "Student Reviews"
|
msgid "Student Reviews"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:47
|
#: lms/lms/doctype/lms_batch/lms_batch.py:48
|
||||||
msgid "Student {0} has already been added to this batch."
|
msgid "Student {0} has already been added to this batch."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -4573,14 +4748,17 @@ msgstr ""
|
|||||||
#: frontend/src/components/CourseCardOverlay.vue:161
|
#: frontend/src/components/CourseCardOverlay.vue:161
|
||||||
#: frontend/src/components/Modals/AnnouncementModal.vue:99
|
#: frontend/src/components/Modals/AnnouncementModal.vue:99
|
||||||
#: frontend/src/components/Modals/AssessmentModal.vue:73
|
#: frontend/src/components/Modals/AssessmentModal.vue:73
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:148
|
#: frontend/src/components/Modals/ChapterModal.vue:153
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:193
|
#: frontend/src/components/Modals/ChapterModal.vue:198
|
||||||
#: frontend/src/components/Modals/Event.vue:255
|
#: frontend/src/components/Modals/Event.vue:255
|
||||||
#: frontend/src/components/Modals/Event.vue:310
|
#: frontend/src/components/Modals/Event.vue:310
|
||||||
#: frontend/src/components/Modals/Question.vue:261
|
#: frontend/src/components/Modals/Question.vue:261
|
||||||
#: frontend/src/components/Modals/Question.vue:312
|
#: frontend/src/components/Modals/Question.vue:312
|
||||||
#: frontend/src/pages/CourseForm.vue:457 frontend/src/pages/QuizForm.vue:342
|
#: frontend/src/pages/CourseForm.vue:460 frontend/src/pages/ProgramForm.vue:226
|
||||||
#: frontend/src/pages/QuizForm.vue:361 frontend/src/pages/QuizForm.vue:430
|
#: 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/pages/QuizForm.vue:362 frontend/src/pages/QuizForm.vue:431
|
||||||
msgid "Success"
|
msgid "Success"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -4635,6 +4813,7 @@ msgstr ""
|
|||||||
#: lms/lms/doctype/lms_live_class/lms_live_class.json
|
#: lms/lms/doctype/lms_live_class/lms_live_class.json
|
||||||
#: lms/lms/doctype/lms_mentor_request/lms_mentor_request.json
|
#: lms/lms/doctype/lms_mentor_request/lms_mentor_request.json
|
||||||
#: lms/lms/doctype/lms_payment/lms_payment.json
|
#: lms/lms/doctype/lms_payment/lms_payment.json
|
||||||
|
#: lms/lms/doctype/lms_program/lms_program.json
|
||||||
#: lms/lms/doctype/lms_question/lms_question.json
|
#: lms/lms/doctype/lms_question/lms_question.json
|
||||||
#: lms/lms/doctype/lms_quiz/lms_quiz.json
|
#: lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||||
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json
|
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json
|
||||||
@@ -4735,11 +4914,15 @@ msgstr ""
|
|||||||
msgid "There are no chapters in this course. Create and manage chapters from here."
|
msgid "There are no chapters in this course. Create and manage chapters from here."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/Courses.vue:150
|
#: frontend/src/pages/Courses.vue:151
|
||||||
msgid "There are no courses available at the moment. Keep an eye out, fresh learning experiences are on the way soon!"
|
msgid "There are no courses available at the moment. Keep an eye out, fresh learning experiences are on the way soon!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_batch/lms_batch.py:141
|
#: frontend/src/pages/Programs.vue:86
|
||||||
|
msgid "There are no programs available at the moment. Keep an eye out, fresh learning experiences are on the way soon!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lms/lms/doctype/lms_batch/lms_batch.py:146
|
||||||
msgid "There are no seats available in this batch."
|
msgid "There are no seats available in this batch."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -4770,11 +4953,11 @@ msgstr ""
|
|||||||
msgid "This course has:"
|
msgid "This course has:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/utils.py:1582
|
#: lms/lms/utils.py:1585
|
||||||
msgid "This course is free."
|
msgid "This course is free."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/SCORMChapter.vue:198
|
#: frontend/src/pages/SCORMChapter.vue:197
|
||||||
msgid "This is a chapter in the course {0}"
|
msgid "This is a chapter in the course {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -4866,6 +5049,7 @@ msgstr ""
|
|||||||
#. Label of the title (Data) field in DocType 'LMS Course'
|
#. Label of the title (Data) field in DocType 'LMS Course'
|
||||||
#. Label of the title (Data) field in DocType 'LMS Exercise'
|
#. Label of the title (Data) field in DocType 'LMS Exercise'
|
||||||
#. Label of the title (Data) field in DocType 'LMS Live Class'
|
#. Label of the title (Data) field in DocType 'LMS Live Class'
|
||||||
|
#. Label of the title (Data) field in DocType 'LMS Program'
|
||||||
#. Label of the title (Data) field in DocType 'LMS Quiz'
|
#. Label of the title (Data) field in DocType 'LMS Quiz'
|
||||||
#. Label of the title (Data) field in DocType 'LMS Sidebar Item'
|
#. Label of the title (Data) field in DocType 'LMS Sidebar Item'
|
||||||
#. Label of the title (Data) field in DocType 'LMS Timetable Template'
|
#. Label of the title (Data) field in DocType 'LMS Timetable Template'
|
||||||
@@ -4873,7 +5057,8 @@ msgstr ""
|
|||||||
#: frontend/src/components/Modals/DiscussionModal.vue:18
|
#: frontend/src/components/Modals/DiscussionModal.vue:18
|
||||||
#: frontend/src/components/Modals/LiveClassModal.vue:23
|
#: frontend/src/components/Modals/LiveClassModal.vue:23
|
||||||
#: frontend/src/pages/BatchForm.vue:20 frontend/src/pages/CourseForm.vue:32
|
#: frontend/src/pages/BatchForm.vue:20 frontend/src/pages/CourseForm.vue:32
|
||||||
#: frontend/src/pages/JobCreation.vue:20 frontend/src/pages/QuizForm.vue:48
|
#: 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/Quizzes.vue:114 lms/lms/doctype/cohort/cohort.json
|
#: frontend/src/pages/Quizzes.vue:114 lms/lms/doctype/cohort/cohort.json
|
||||||
#: lms/lms/doctype/cohort_subgroup/cohort_subgroup.json
|
#: lms/lms/doctype/cohort_subgroup/cohort_subgroup.json
|
||||||
#: lms/lms/doctype/cohort_web_page/cohort_web_page.json
|
#: lms/lms/doctype/cohort_web_page/cohort_web_page.json
|
||||||
@@ -4886,6 +5071,7 @@ msgstr ""
|
|||||||
#: lms/lms/doctype/lms_course/lms_course.json
|
#: lms/lms/doctype/lms_course/lms_course.json
|
||||||
#: lms/lms/doctype/lms_exercise/lms_exercise.json
|
#: lms/lms/doctype/lms_exercise/lms_exercise.json
|
||||||
#: lms/lms/doctype/lms_live_class/lms_live_class.json
|
#: lms/lms/doctype/lms_live_class/lms_live_class.json
|
||||||
|
#: lms/lms/doctype/lms_program/lms_program.json
|
||||||
#: lms/lms/doctype/lms_quiz/lms_quiz.json
|
#: lms/lms/doctype/lms_quiz/lms_quiz.json
|
||||||
#: lms/lms/doctype/lms_sidebar_item/lms_sidebar_item.json
|
#: lms/lms/doctype/lms_sidebar_item/lms_sidebar_item.json
|
||||||
#: lms/lms/doctype/lms_timetable_template/lms_timetable_template.json
|
#: lms/lms/doctype/lms_timetable_template/lms_timetable_template.json
|
||||||
@@ -4894,7 +5080,7 @@ msgstr ""
|
|||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/components/Modals/ChapterModal.vue:169
|
#: frontend/src/components/Modals/ChapterModal.vue:174
|
||||||
msgid "Title is required"
|
msgid "Title is required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -4909,7 +5095,7 @@ msgstr ""
|
|||||||
msgid "To Date"
|
msgid "To Date"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/utils.py:1593
|
#: lms/lms/utils.py:1596
|
||||||
msgid "To join this batch, please contact the Administrator."
|
msgid "To join this batch, please contact the Administrator."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -4973,7 +5159,7 @@ msgstr ""
|
|||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/components/Quiz.vue:580
|
#: frontend/src/components/Quiz.vue:583
|
||||||
msgid "Type your answer"
|
msgid "Type your answer"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -5257,7 +5443,7 @@ msgstr ""
|
|||||||
msgid "You are not enrolled in this course. Please enroll to access this lesson."
|
msgid "You are not enrolled in this course. Please enroll to access this lesson."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/Courses.vue:134
|
#: frontend/src/pages/Courses.vue:135
|
||||||
msgid "You can add chapters and lessons to it."
|
msgid "You can add chapters and lessons to it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -5429,6 +5615,10 @@ msgstr ""
|
|||||||
msgid "jane@example.com"
|
msgid "jane@example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: frontend/src/pages/Programs.vue:32
|
||||||
|
msgid "members"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: lms/templates/quiz/quiz.html:106
|
#: lms/templates/quiz/quiz.html:106
|
||||||
msgid "of"
|
msgid "of"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -5441,7 +5631,7 @@ msgstr ""
|
|||||||
msgid "posted by"
|
msgid "posted by"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: frontend/src/pages/QuizForm.vue:389
|
#: frontend/src/pages/QuizForm.vue:390
|
||||||
msgid "question_detail"
|
msgid "question_detail"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -5473,7 +5663,7 @@ msgstr ""
|
|||||||
msgid "{0} has submitted the assignment {1}"
|
msgid "{0} has submitted the assignment {1}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_enrollment/lms_enrollment.py:53
|
#: lms/lms/doctype/lms_enrollment/lms_enrollment.py:57
|
||||||
msgid "{0} is already a Student of {1} course through {2} batch"
|
msgid "{0} is already a Student of {1} course through {2} batch"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -5481,7 +5671,7 @@ msgstr ""
|
|||||||
msgid "{0} is already a mentor for course {1}"
|
msgid "{0} is already a mentor for course {1}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lms/lms/doctype/lms_enrollment/lms_enrollment.py:26
|
#: lms/lms/doctype/lms_enrollment/lms_enrollment.py:30
|
||||||
msgid "{0} is already a {1} of the course {2}"
|
msgid "{0} is already a {1} of the course {2}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: frappe\n"
|
"Project-Id-Version: frappe\n"
|
||||||
"Report-Msgid-Bugs-To: jannat@frappe.io\n"
|
"Report-Msgid-Bugs-To: jannat@frappe.io\n"
|
||||||
"POT-Creation-Date: 2024-11-15 16:04+0000\n"
|
"POT-Creation-Date: 2024-11-15 16:04+0000\n"
|
||||||
"PO-Revision-Date: 2024-11-18 17:31\n"
|
"PO-Revision-Date: 2024-11-24 19:19\n"
|
||||||
"Last-Translator: jannat@frappe.io\n"
|
"Last-Translator: jannat@frappe.io\n"
|
||||||
"Language-Team: Swedish\n"
|
"Language-Team: Swedish\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@@ -78,7 +78,7 @@ msgstr "Godkännande av Villkor och/eller Principer"
|
|||||||
#. Option for the 'Status' (Select) field in DocType 'Cohort Join Request'
|
#. Option for the 'Status' (Select) field in DocType 'Cohort Join Request'
|
||||||
#: lms/lms/doctype/cohort_join_request/cohort_join_request.json
|
#: lms/lms/doctype/cohort_join_request/cohort_join_request.json
|
||||||
msgid "Accepted"
|
msgid "Accepted"
|
||||||
msgstr "Godkänd"
|
msgstr "Accepterad"
|
||||||
|
|
||||||
#. Label of the account_id (Data) field in DocType 'Zoom Settings'
|
#. Label of the account_id (Data) field in DocType 'Zoom Settings'
|
||||||
#: lms/lms/doctype/zoom_settings/zoom_settings.json
|
#: lms/lms/doctype/zoom_settings/zoom_settings.json
|
||||||
|
|||||||
1699
lms/locale/zh.po
1699
lms/locale/zh.po
File diff suppressed because it is too large
Load Diff
@@ -93,4 +93,5 @@ lms.patches.v2_0.sidebar_settings
|
|||||||
lms.patches.v2_0.delete_certificate_request_notification #18-09-2024
|
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.add_course_statistics #21-10-2024
|
||||||
lms.patches.v2_0.give_discussions_permissions
|
lms.patches.v2_0.give_discussions_permissions
|
||||||
lms.patches.v2_0.delete_web_forms
|
lms.patches.v2_0.delete_web_forms
|
||||||
|
lms.patches.v2_0.update_desk_access_for_lms_roles
|
||||||
9
lms/patches/v2_0/update_desk_access_for_lms_roles.py
Normal file
9
lms/patches/v2_0/update_desk_access_for_lms_roles.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
roles = ["Course Creator", "Moderator", "Batch Evaluator", "LMS Student"]
|
||||||
|
|
||||||
|
for role in roles:
|
||||||
|
if frappe.db.exists("Role", role):
|
||||||
|
frappe.db.set_value("Role", role, "desk_access", 0)
|
||||||
Reference in New Issue
Block a user