Compare commits

..

1 Commits

Author SHA1 Message Date
frappe-pr-bot
7fac29e3e4 chore: update POT file 2024-10-25 10:37:03 +00:00
54 changed files with 5179 additions and 68734 deletions

View File

@@ -13,6 +13,6 @@ module.exports = defineConfig({
openMode: 0, openMode: 0,
}, },
e2e: { e2e: {
baseUrl: "http://test:8000", baseUrl: "http://test_site_ui:8000",
}, },
}); });

View File

@@ -5,7 +5,7 @@ describe("Course Creation", () => {
cy.visit("/lms/courses"); cy.visit("/lms/courses");
// Create a course // Create a course
cy.get("header").children().last().children().last().click(); cy.get("a").contains("New").click();
cy.wait(1000); cy.wait(1000);
cy.url().should("include", "/courses/new/edit"); cy.url().should("include", "/courses/new/edit");
@@ -73,7 +73,7 @@ describe("Course Creation", () => {
.should("be.visible") .should("be.visible")
.within(() => { .within(() => {
cy.get("label").contains("Title").type("Test Chapter"); cy.get("label").contains("Title").type("Test Chapter");
cy.button("Create").click(); cy.button("Add Chapter").click();
}); });
// Add Lesson // Add Lesson

View File

@@ -23,7 +23,7 @@
"codemirror-editor-vue3": "^2.8.0", "codemirror-editor-vue3": "^2.8.0",
"dayjs": "^1.11.6", "dayjs": "^1.11.6",
"feather-icons": "^4.28.0", "feather-icons": "^4.28.0",
"frappe-ui": "^0.1.72", "frappe-ui": "^0.1.69",
"lucide-vue-next": "^0.383.0", "lucide-vue-next": "^0.383.0",
"markdown-it": "^14.0.0", "markdown-it": "^14.0.0",
"pinia": "^2.0.33", "pinia": "^2.0.33",

View File

@@ -25,7 +25,7 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import { createResource, Avatar } from 'frappe-ui' import { createListResource, Avatar } from 'frappe-ui'
import { timeAgo } from '@/utils' import { timeAgo } from '@/utils'
const props = defineProps({ const props = defineProps({
@@ -35,15 +35,24 @@ const props = defineProps({
}, },
}) })
const communications = createResource({ const communications = createListResource({
url: 'lms.lms.api.get_announcements', doctype: 'Communication',
makeParams(value) { fields: [
return { 'subject',
batch: props.batch, 'content',
} 'recipients',
'cc',
'communication_date',
'sender',
'sender_full_name',
],
filters: {
reference_doctype: 'LMS Batch',
reference_name: props.batch,
}, },
orderBy: 'communication_date desc',
auto: true, auto: true,
cache: ['announcement', props.batch], cache: ['batch', props.batch],
}) })
</script> </script>
<style> <style>

View File

@@ -2,7 +2,6 @@
<div> <div>
<label class="block mb-1" :class="labelClasses" v-if="label"> <label class="block mb-1" :class="labelClasses" v-if="label">
{{ label }} {{ label }}
<span class="text-red-500" v-if="required">*</span>
</label> </label>
<div class="grid grid-cols-3 gap-1"> <div class="grid grid-cols-3 gap-1">
<Button <Button
@@ -116,9 +115,6 @@ const props = defineProps({
type: Function, type: Function,
default: (value) => `${value} is an Invalid value`, default: (value) => `${value} is an Invalid value`,
}, },
required: {
type: Boolean,
},
}) })
const values = defineModel() const values = defineModel()

View File

@@ -30,29 +30,29 @@
</div> </div>
<div class="flex flex-col flex-auto p-4"> <div class="flex flex-col flex-auto p-4">
<div class="flex items-center justify-between mb-2"> <div class="flex items-center justify-between mb-2">
<div v-if="course.lessons"> <div v-if="course.lesson_count">
<Tooltip :text="__('Lessons')"> <Tooltip :text="__('Lessons')">
<span class="flex items-center"> <span class="flex items-center">
<BookOpen class="h-4 w-4 stroke-1.5 text-gray-700 mr-1" /> <BookOpen class="h-4 w-4 stroke-1.5 text-gray-700 mr-1" />
{{ course.lessons }} {{ course.lesson_count }}
</span> </span>
</Tooltip> </Tooltip>
</div> </div>
<div v-if="course.enrollments"> <div v-if="course.enrollment_count">
<Tooltip :text="__('Enrolled Students')"> <Tooltip :text="__('Enrolled Students')">
<span class="flex items-center"> <span class="flex items-center">
<Users class="h-4 w-4 stroke-1.5 text-gray-700 mr-1" /> <Users class="h-4 w-4 stroke-1.5 text-gray-700 mr-1" />
{{ course.enrollments }} {{ course.enrollment_count }}
</span> </span>
</Tooltip> </Tooltip>
</div> </div>
<div v-if="course.rating"> <div v-if="course.avg_rating">
<Tooltip :text="__('Average Rating')"> <Tooltip :text="__('Average Rating')">
<span class="flex items-center"> <span class="flex items-center">
<Star class="h-4 w-4 stroke-1.5 text-gray-700 mr-1" /> <Star class="h-4 w-4 stroke-1.5 text-gray-700 mr-1" />
{{ course.rating }} {{ course.avg_rating }}
</span> </span>
</Tooltip> </Tooltip>
</div> </div>

View File

@@ -93,19 +93,21 @@
<div class="flex items-center mb-3"> <div class="flex items-center mb-3">
<BookOpen class="h-5 w-5 stroke-1.5 text-gray-600" /> <BookOpen class="h-5 w-5 stroke-1.5 text-gray-600" />
<span class="ml-2"> <span class="ml-2">
{{ course.data.lessons }} {{ __('Lessons') }} {{ course.data.lesson_count }} {{ __('Lessons') }}
</span> </span>
</div> </div>
<div class="flex items-center mb-3"> <div class="flex items-center mb-3">
<Users class="h-5 w-5 stroke-1.5 text-gray-600" /> <Users class="h-5 w-5 stroke-1.5 text-gray-600" />
<span class="ml-2"> <span class="ml-2">
{{ formatAmount(course.data.enrollments) }} {{ course.data.enrollment_count_formatted }}
{{ __('Enrolled Students') }} {{ __('Enrolled Students') }}
</span> </span>
</div> </div>
<div class="flex items-center"> <div class="flex items-center">
<Star class="h-5 w-5 stroke-1.5 fill-orange-500 text-gray-50" /> <Star class="h-5 w-5 stroke-1.5 fill-orange-500 text-gray-50" />
<span class="ml-2"> {{ course.data.rating }} {{ __('Rating') }} </span> <span class="ml-2">
{{ course.data.avg_rating }} {{ __('Rating') }}
</span>
</div> </div>
</div> </div>
</div> </div>
@@ -114,7 +116,7 @@
import { BookOpen, Users, Star } from 'lucide-vue-next' import { BookOpen, Users, Star } from 'lucide-vue-next'
import { computed, inject } from 'vue' import { computed, inject } from 'vue'
import { Button, createResource } from 'frappe-ui' import { Button, createResource } from 'frappe-ui'
import { showToast, formatAmount } from '@/utils/' import { showToast } from '@/utils/'
import { capture } from '@/telemetry' import { capture } from '@/telemetry'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'

View File

@@ -76,7 +76,7 @@ const props = defineProps({
required: true, required: true,
}, },
avg_rating: { avg_rating: {
type: String, type: Number,
required: true, required: true,
}, },
membership: { membership: {

View File

@@ -21,7 +21,7 @@
<div class="space-y-2"> <div class="space-y-2">
<div <div
class="flex text-sm font-medium space-x-2 cursor-pointer" class="flex items-center text-sm font-medium space-x-2 cursor-pointer"
@click="openHelpDialog('upload')" @click="openHelpDialog('upload')"
> >
<span class="leading-5"> <span class="leading-5">
@@ -56,21 +56,6 @@
}} }}
</div> </div>
</div> </div>
<div class="space-y-2">
<div class="flex items-center text-sm font-medium space-x-2">
<span>
{{ __('What does include in preview mean?') }}
</span>
</div>
<div class="text-xs text-gray-600 mb-1 leading-5">
{{
__(
'If Include in Preview is enabled for a lesson then the lesson will also be accessible to non logged in users.'
)
}}
</div>
</div>
</div> </div>
<ExplanationVideos v-model="showExplanation" :type="type" /> <ExplanationVideos v-model="showExplanation" :type="type" />
</template> </template>

View File

@@ -48,7 +48,7 @@
<a <a
:href="cls.join_url" :href="cls.join_url"
target="_blank" target="_blank"
class="w-full cursor-pointer inline-flex items-center justify-center gap-2 transition-colors focus:outline-none text-gray-800 bg-gray-100 hover:bg-gray-200 active:bg-gray-300 focus-visible:ring focus-visible:ring-gray-400 h-7 text-base px-2 rounded" class="w-1/2 cursor-pointer inline-flex items-center justify-center gap-2 transition-colors focus:outline-none text-gray-800 bg-gray-100 hover:bg-gray-200 active:bg-gray-300 focus-visible:ring focus-visible:ring-gray-400 h-7 text-base px-2 rounded"
> >
<Video class="h-4 w-4 stroke-1.5" /> <Video class="h-4 w-4 stroke-1.5" />
{{ __('Join') }} {{ __('Join') }}

View File

@@ -44,7 +44,7 @@
<script setup> <script setup>
import { Dialog, Input, TextEditor, createResource } from 'frappe-ui' import { Dialog, Input, TextEditor, createResource } from 'frappe-ui'
import { reactive } from 'vue' import { reactive } from 'vue'
import { showToast } from '@/utils/' import { createToast } from '@/utils/'
const show = defineModel() const show = defineModel()
@@ -94,14 +94,22 @@ const makeAnnouncement = (close) => {
}, },
onSuccess() { onSuccess() {
close() close()
showToast( createToast({
__('Success'), title: 'Success',
__('Announcement has been sent successfully'), text: 'Announcement has been sent successfully',
'check' icon: 'Check',
) iconClasses: 'bg-green-600 text-white rounded-md p-px',
})
}, },
onError(err) { onError(err) {
showToast(__('Error'), __(err.messages?.[0] || err), 'check') createToast({
title: 'Error',
text: err.messages?.[0] || err,
icon: 'x',
iconClasses: 'bg-red-600 text-white rounded-md p-px',
position: 'top-center',
timeout: 10,
})
}, },
} }
) )

View File

@@ -2,11 +2,11 @@
<Dialog <Dialog
v-model="show" v-model="show"
:options="{ :options="{
title: chapterDetail ? __('Edit Chapter') : __('Add Chapter'), title: __('Add Chapter'),
size: 'lg', size: 'lg',
actions: [ actions: [
{ {
label: chapterDetail ? __('Edit') : __('Create'), label: chapterDetail ? __('Edit Chapter') : __('Add Chapter'),
variant: 'solid', variant: 'solid',
onClick: (close) => onClick: (close) =>
chapterDetail ? editChapter(close) : addChapter(close), chapterDetail ? editChapter(close) : addChapter(close),

View File

@@ -1,7 +1,7 @@
<template> <template>
<div v-if="quiz.data"> <div v-if="quiz.data">
<div <div
class="bg-blue-100 space-y-1 py-2 px-2 mb-4 rounded-md text-sm text-blue-800" class="bg-blue-100 space-y-1 py-2 px-2 rounded-md text-sm text-blue-800"
> >
<div class="leading-5"> <div class="leading-5">
{{ {{

View File

@@ -236,7 +236,7 @@ const breadcrumbs = computed(() => {
const isStudent = computed(() => { const isStudent = computed(() => {
return ( return (
user?.data && user?.data &&
batch.data?.students?.length && batch.data?.students.length &&
batch.data?.students.includes(user.data.name) batch.data?.students.includes(user.data.name)
) )
}) })

View File

@@ -32,65 +32,57 @@
</div> </div>
</div> </div>
<div class="mb-4"> <div class="mb-4">
<div class="text-xs text-gray-600 mb-2"> <div>
{{ __('Meta Image') }} <FileUploader
</div> v-if="!batch.image"
<FileUploader class="mt-4"
v-if="!batch.image" :fileTypes="['image/*']"
:fileTypes="['image/*']" :validateFile="validateFile"
:validateFile="validateFile" @success="(file) => saveImage(file)"
@success="(file) => saveImage(file)" >
> <template v-slot="{ file, progress, uploading, openFileSelector }">
<template v-slot="{ file, progress, uploading, openFileSelector }"> <div class="mb-4">
<div class="flex items-center"> <Button @click="openFileSelector" :loading="uploading">
<div class="border rounded-md w-fit py-5 px-20"> {{ uploading ? `Uploading ${progress}%` : 'Upload an image' }}
<Image class="size-5 stroke-1 text-gray-700" />
</div>
<div class="ml-4">
<Button @click="openFileSelector">
{{ __('Upload') }}
</Button> </Button>
<div class="mt-2 text-gray-600 text-sm">
{{
__(
'Appears when the batch URL is shared on any online platform'
)
}}
</div>
</div> </div>
</template>
</FileUploader>
<div v-else class="mb-4">
<div class="text-xs text-gray-600 mb-1">
{{ __('Meta Image') }}
</div> </div>
</template> <div class="flex items-center">
</FileUploader> <div class="border rounded-md p-2 mr-2">
<div v-else class="mb-4"> <FileText class="h-5 w-5 stroke-1.5 text-gray-700" />
<div class="flex items-center">
<img :src="batch.image.file_url" class="border rounded-md w-40" />
<div class="ml-4">
<Button @click="removeImage()">
{{ __('Remove') }}
</Button>
<div class="mt-2 text-gray-600 text-sm">
{{
__(
'Appears when the batch URL is shared on any online platform'
)
}}
</div> </div>
<div class="flex flex-col">
<span>
{{ batch.image.file_name }}
</span>
<span class="text-sm text-gray-500 mt-1">
{{ getFileSize(batch.image.file_size) }}
</span>
</div>
<X
@click="removeImage()"
class="bg-gray-200 rounded-md cursor-pointer stroke-1.5 w-5 h-5 p-1 ml-4"
/>
</div> </div>
</div> </div>
</div> </div>
<MultiSelect
v-model="instructors"
doctype="User"
:label="__('Instructors')"
/>
</div> </div>
<MultiSelect
v-model="instructors"
doctype="User"
:label="__('Instructors')"
/>
<div class="mb-4"> <div class="mb-4">
<FormControl <FormControl
v-model="batch.description" v-model="batch.description"
:label="__('Description')" :label="__('Description')"
type="textarea" type="textarea"
class="my-4" class="my-4"
:placeholder="__('Short description of the batch')"
/> />
<div> <div>
<label class="block text-sm text-gray-600 mb-1"> <label class="block text-sm text-gray-600 mb-1">
@@ -141,7 +133,6 @@
v-model="batch.timezone" v-model="batch.timezone"
:label="__('Timezone')" :label="__('Timezone')"
type="text" type="text"
:placeholder="__('Example: IST (+5:30)')"
class="mb-4" class="mb-4"
/> />
</div> </div>
@@ -158,7 +149,6 @@
:label="__('Seat Count')" :label="__('Seat Count')"
type="number" type="number"
class="mb-4" class="mb-4"
:placeholder="__('Number of seats available')"
/> />
<FormControl <FormControl
v-model="batch.evaluation_end_date" v-model="batch.evaluation_end_date"
@@ -238,11 +228,11 @@ import {
createResource, createResource,
} from 'frappe-ui' } from 'frappe-ui'
import Link from '@/components/Controls/Link.vue' import Link from '@/components/Controls/Link.vue'
import { useRouter } from 'vue-router'
import { showToast } from '../utils'
import { Image } from 'lucide-vue-next'
import { capture } from '@/telemetry'
import MultiSelect from '@/components/Controls/MultiSelect.vue' import MultiSelect from '@/components/Controls/MultiSelect.vue'
import { useRouter } from 'vue-router'
import { getFileSize, showToast } from '../utils'
import { X, FileText } from 'lucide-vue-next'
import { capture } from '@/telemetry'
const router = useRouter() const router = useRouter()
const user = inject('$user') const user = inject('$user')

View File

@@ -40,7 +40,6 @@
{{ __('Loading Batches...') }} {{ __('Loading Batches...') }}
</div> </div>
<Tabs <Tabs
v-if="hasBatches"
v-model="tabIndex" v-model="tabIndex"
:tabs="makeTabs" :tabs="makeTabs"
tablistClass="overflow-x-visible flex-wrap !gap-3 md:flex-nowrap" tablistClass="overflow-x-visible flex-wrap !gap-3 md:flex-nowrap"
@@ -80,63 +79,24 @@
<BatchCard :batch="batch" /> <BatchCard :batch="batch" />
</router-link> </router-link>
</div> </div>
<div v-else class="p-5 italic text-gray-500"> <div
{{ __('No {0} batches').format(tab.label.toLowerCase()) }} v-else
class="grid flex-1 place-items-center text-xl font-medium text-gray-500"
>
<div class="flex flex-col items-center justify-center mt-4">
<div>
{{ __('No {0} batches found').format(tab.label.toLowerCase()) }}
</div>
</div>
</div> </div>
</template> </template>
</Tabs> </Tabs>
<div
v-else-if="
!batches.loading &&
!hasBatches &&
(user.data?.is_instructor || user.data?.is_moderator)
"
class="grid grid-cols-3 p-5"
>
<router-link
:to="{
name: 'BatchForm',
params: {
batchName: 'new',
},
}"
>
<div class="bg-gray-50 py-32 px-5 rounded-md">
<div class="flex flex-col items-center text-center space-y-2">
<Plus
class="size-10 stroke-1 text-gray-800 p-1 rounded-full border bg-white"
/>
<div class="font-medium">
{{ __('Create a Batch') }}
</div>
<span class="text-gray-700 text-sm leading-4">
{{ __('You can link courses and assessments to it.') }}
</span>
</div>
</div>
</router-link>
</div>
<div
v-else-if="!batches.loading && !hasBatches"
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 batches found') }}
</div>
<div>
{{
__(
'There are no batches available at the moment. Keep an eye out, fresh learning experiences are on the way soon!'
)
}}
</div>
</div>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { import {
createListResource,
createResource, createResource,
Breadcrumbs, Breadcrumbs,
Button, Button,
@@ -144,14 +104,13 @@ import {
Badge, Badge,
Select, Select,
} from 'frappe-ui' } from 'frappe-ui'
import { BookOpen, Plus } from 'lucide-vue-next' import { Plus } from 'lucide-vue-next'
import BatchCard from '@/components/BatchCard.vue' import BatchCard from '@/components/BatchCard.vue'
import { inject, ref, computed, onMounted, watch } from 'vue' import { inject, ref, computed, onMounted, watch } from 'vue'
import { updateDocumentTitle } from '@/utils' import { updateDocumentTitle } from '@/utils'
const user = inject('$user') const user = inject('$user')
const currentCategory = ref(null) const currentCategory = ref(null)
const hasBatches = ref(false)
onMounted(() => { onMounted(() => {
let queries = new URLSearchParams(location.search) let queries = new URLSearchParams(location.search)
@@ -160,10 +119,10 @@ onMounted(() => {
} }
}) })
const batches = createResource({ const batches = createListResource({
doctype: 'LMS Batch', doctype: 'LMS Batch',
url: 'lms.lms.utils.get_batches', url: 'lms.lms.utils.get_batches',
cache: ['batches', user.data?.email], cache: ['batches', user?.data?.email],
auto: true, auto: true,
}) })
@@ -224,14 +183,6 @@ const addToTabs = (label) => {
}) })
} }
watch(batches, () => {
Object.keys(batches.data).forEach((key) => {
if (batches.data[key].length) {
hasBatches.value = true
}
})
})
watch( watch(
() => currentCategory.value, () => currentCategory.value,
() => { () => {

View File

@@ -16,16 +16,16 @@
</div> </div>
<div class="flex items-center"> <div class="flex items-center">
<Tooltip <Tooltip
v-if="course.data.rating" v-if="course.data.avg_rating"
:text="__('Average Rating')" :text="__('Average Rating')"
class="flex items-center" class="flex items-center"
> >
<Star class="h-5 w-5 text-gray-100 fill-orange-500" /> <Star class="h-5 w-5 text-gray-100 fill-orange-500" />
<span class="ml-1"> <span class="ml-1">
{{ course.data.rating }} {{ course.data.avg_rating }}
</span> </span>
</Tooltip> </Tooltip>
<span v-if="course.data.rating" class="mx-3">&middot;</span> <span v-if="course.data.avg_rating" class="mx-3">&middot;</span>
<Tooltip <Tooltip
v-if="course.data.enrollment_count" v-if="course.data.enrollment_count"
:text="__('Enrolled Students')" :text="__('Enrolled Students')"
@@ -74,7 +74,7 @@
</div> </div>
<CourseReviews <CourseReviews
:courseName="course.data.name" :courseName="course.data.name"
:avg_rating="course.data.rating" :avg_rating="course.data.avg_rating"
:membership="course.data.membership" :membership="course.data.membership"
/> />
</div> </div>
@@ -116,7 +116,7 @@ const breadcrumbs = computed(() => {
let items = [{ label: 'All Courses', route: { name: 'Courses' } }] let items = [{ label: 'All Courses', route: { name: 'Courses' } }]
items.push({ items.push({
label: course?.data?.title, label: course?.data?.title,
route: { name: 'CourseDetail', params: { courseName: course?.data?.name } }, route: { name: 'CourseDetail', params: { course: course?.data?.name } },
}) })
return items return items
}) })

View File

@@ -23,23 +23,15 @@
v-model="course.title" v-model="course.title"
:label="__('Title')" :label="__('Title')"
class="mb-4" class="mb-4"
:required="true"
/> />
<FormControl <FormControl
v-model="course.short_introduction" v-model="course.short_introduction"
:label="__('Short Introduction')" :label="__('Short Introduction')"
:placeholder="
__(
'A one line introduction to the course that appears on the course card'
)
"
class="mb-4" class="mb-4"
:required="true"
/> />
<div class="mb-4"> <div class="mb-4">
<div class="mb-1.5 text-sm text-gray-600"> <div class="mb-1.5 text-sm text-gray-700">
{{ __('Course Description') }} {{ __('Course Description') }}
<span class="text-red-500">*</span>
</div> </div>
<TextEditor <TextEditor
:content="course.description" :content="course.description"
@@ -49,62 +41,49 @@
editorClass="prose-sm max-w-none border-b border-x bg-gray-100 rounded-b-md py-1 px-2 min-h-[7rem]" editorClass="prose-sm max-w-none border-b border-x bg-gray-100 rounded-b-md py-1 px-2 min-h-[7rem]"
/> />
</div> </div>
<div class="mb-4"> <FileUploader
<div class="text-xs text-gray-600 mb-2"> v-if="!course.course_image"
{{ __('Course Image') }} :fileTypes="['image/*']"
<span class="text-red-500">*</span> :validateFile="validateFile"
</div> @success="(file) => saveImage(file)"
<FileUploader >
v-if="!course.course_image" <template
:fileTypes="['image/*']" v-slot="{ file, progress, uploading, openFileSelector }"
:validateFile="validateFile"
@success="(file) => saveImage(file)"
> >
<template <div class="mb-4">
v-slot="{ file, progress, uploading, openFileSelector }" <Button @click="openFileSelector" :loading="uploading">
> {{
<div class="flex items-center"> uploading ? `Uploading ${progress}%` : 'Upload an image'
<div class="border rounded-md w-fit py-5 px-20"> }}
<Image class="size-5 stroke-1 text-gray-700" /> </Button>
</div>
<div class="ml-4">
<Button @click="openFileSelector">
{{ __('Upload') }}
</Button>
<div class="mt-2 text-gray-600 text-sm">
{{
__('Appears on the course card in the course list')
}}
</div>
</div>
</div>
</template>
</FileUploader>
<div v-else class="mb-4">
<div class="flex items-center">
<img
:src="course.course_image.file_url"
class="border rounded-md w-40"
/>
<div class="ml-4">
<Button @click="removeImage()">
{{ __('Remove') }}
</Button>
<div class="mt-2 text-gray-600 text-sm">
{{ __('Appears on the course card in the course list') }}
</div>
</div>
</div> </div>
</template>
</FileUploader>
<div v-else class="mb-4">
<div class="text-xs text-gray-600 mb-1">
{{ __('Course Image') }}
</div>
<div class="flex items-center">
<div class="border rounded-md p-2 mr-2">
<FileText class="h-5 w-5 stroke-1.5 text-gray-700" />
</div>
<div class="flex flex-col">
<span>
{{ course.course_image.file_name }}
</span>
<span class="text-sm text-gray-500 mt-1">
{{ getFileSize(course.course_image.file_size) }}
</span>
</div>
<X
@click="removeImage()"
class="bg-gray-200 rounded-md cursor-pointer stroke-1.5 w-5 h-5 p-1 ml-4"
/>
</div> </div>
</div> </div>
<FormControl <FormControl
v-model="course.video_link" v-model="course.video_link"
:label="__('Preview Video')" :label="__('Preview Video')"
:placeholder="
__(
'Paste the youtube link of a short video introducing the course'
)
"
class="mb-4" class="mb-4"
/> />
<div class="mb-4"> <div class="mb-4">
@@ -125,8 +104,6 @@
</div> </div>
<FormControl <FormControl
v-model="newTag" v-model="newTag"
:placeholder="__('Keywords for the course')"
class="w-52"
@keyup.enter="updateTags()" @keyup.enter="updateTags()"
id="tags" id="tags"
/> />
@@ -144,7 +121,6 @@
v-model="instructors" v-model="instructors"
doctype="User" doctype="User"
:label="__('Instructors')" :label="__('Instructors')"
:required="true"
/> />
</div> </div>
<div class="container border-t"> <div class="container border-t">
@@ -154,7 +130,7 @@
<div class="grid grid-cols-3 gap-10 mb-4"> <div class="grid grid-cols-3 gap-10 mb-4">
<div <div
v-if="user.data?.is_moderator" v-if="user.data?.is_moderator"
class="flex flex-col space-y-4" class="flex flex-col space-y-3"
> >
<FormControl <FormControl
type="checkbox" type="checkbox"
@@ -248,9 +224,14 @@ import {
reactive, reactive,
watch, watch,
} from 'vue' } from 'vue'
import { convertToTitleCase, showToast, updateDocumentTitle } from '@/utils' import {
convertToTitleCase,
showToast,
getFileSize,
updateDocumentTitle,
} from '@/utils'
import Link from '@/components/Controls/Link.vue' import Link from '@/components/Controls/Link.vue'
import { FileText, Image, X } from 'lucide-vue-next' import { FileText, X } from 'lucide-vue-next'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import CourseOutline from '@/components/CourseOutline.vue' import CourseOutline from '@/components/CourseOutline.vue'
import MultiSelect from '@/components/Controls/MultiSelect.vue' import MultiSelect from '@/components/Controls/MultiSelect.vue'

View File

@@ -8,7 +8,7 @@
:items="[{ label: __('Courses'), route: { name: 'Courses' } }]" :items="[{ label: __('Courses'), route: { name: 'Courses' } }]"
/> />
<div class="flex space-x-2 justify-end"> <div class="flex space-x-2 justify-end">
<div class="w-40 md:w-44"> <div class="w-46 md:w-44">
<FormControl <FormControl
v-if="categories.data?.length" v-if="categories.data?.length"
type="select" type="select"
@@ -48,7 +48,6 @@
</header> </header>
<div class=""> <div class="">
<Tabs <Tabs
v-if="hasCourses"
v-model="tabIndex" v-model="tabIndex"
tablistClass="overflow-x-visible flex-wrap !gap-3 md:flex-nowrap" tablistClass="overflow-x-visible flex-wrap !gap-3 md:flex-nowrap"
:tabs="makeTabs" :tabs="makeTabs"
@@ -102,57 +101,18 @@
<CourseCard :course="course" /> <CourseCard :course="course" />
</router-link> </router-link>
</div> </div>
<div v-else class="p-5 italic text-gray-500"> <div
{{ __('No {0} courses').format(tab.label.toLowerCase()) }} v-else
class="grid flex-1 place-items-center text-xl font-medium text-gray-500"
>
<div class="flex flex-col items-center justify-center mt-4">
<div>
{{ __('No {0} courses found').format(tab.label.toLowerCase()) }}
</div>
</div>
</div> </div>
</template> </template>
</Tabs> </Tabs>
<div
v-else-if="
!courses.loading &&
(user.data?.is_moderator || user.data?.is_instructor)
"
class="grid grid-cols-3 p-5"
>
<router-link
:to="{
name: 'CourseForm',
params: {
courseName: 'new',
},
}"
>
<div class="bg-gray-50 py-32 px-5 rounded-md">
<div class="flex flex-col items-center text-center space-y-2">
<Plus
class="size-10 stroke-1 text-gray-800 p-1 rounded-full border bg-white"
/>
<div class="font-medium">
{{ __('Create a Course') }}
</div>
<span class="text-gray-700 text-sm leading-4">
{{ __('You can add chapters and lessons to it.') }}
</span>
</div>
</div>
</router-link>
</div>
<div
v-else-if="!courses.loading && !hasCourses"
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 courses found') }}
</div>
<div>
{{
__(
'There are no courses available at the moment. Keep an eye out, fresh learning experiences are on the way soon!'
)
}}
</div>
</div>
</div> </div>
</div> </div>
</template> </template>
@@ -167,14 +127,13 @@ import {
createResource, createResource,
} 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 { 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'
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)
onMounted(() => { onMounted(() => {
let queries = new URLSearchParams(location.search) let queries = new URLSearchParams(location.search)
@@ -264,16 +223,6 @@ const categories = createResource({
}, },
}) })
watch(courses, () => {
if (courses.data) {
Object.keys(courses.data).forEach((section) => {
if (courses.data[section].length) {
hasCourses.value = true
}
})
}
})
watch( watch(
() => currentCategory.value, () => currentCategory.value,
() => { () => {

View File

@@ -17,9 +17,14 @@
) )
}} }}
</p> </p>
<Button v-if="user.data" @click="enrollStudent()" variant="solid"> <router-link
{{ __('Start Learning') }} v-if="user.data"
</Button> :to="{ name: 'CourseDetail', params: { courseName: courseName } }"
>
<Button variant="solid">
{{ __('Start Learning') }}
</Button>
</router-link>
<Button v-else @click="redirectToLogin()"> <Button v-else @click="redirectToLogin()">
{{ __('Login') }} {{ __('Login') }}
</Button> </Button>
@@ -189,7 +194,7 @@ import { createResource, Breadcrumbs, Button } from 'frappe-ui'
import { computed, watch, inject, ref, onMounted, onBeforeUnmount } from 'vue' import { computed, watch, inject, ref, onMounted, onBeforeUnmount } from 'vue'
import CourseOutline from '@/components/CourseOutline.vue' import CourseOutline from '@/components/CourseOutline.vue'
import UserAvatar from '@/components/UserAvatar.vue' import UserAvatar from '@/components/UserAvatar.vue'
import { useRouter, useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { ChevronLeft, ChevronRight } from 'lucide-vue-next' import { ChevronLeft, ChevronRight } from 'lucide-vue-next'
import Discussions from '@/components/Discussions.vue' import Discussions from '@/components/Discussions.vue'
import { getEditorTools, updateDocumentTitle } from '../utils' import { getEditorTools, updateDocumentTitle } from '../utils'
@@ -199,7 +204,6 @@ import CourseInstructors from '@/components/CourseInstructors.vue'
import ProgressBar from '@/components/ProgressBar.vue' import ProgressBar from '@/components/ProgressBar.vue'
const user = inject('$user') const user = inject('$user')
const router = useRouter()
const route = useRoute() const route = useRoute()
const allowDiscussions = ref(false) const allowDiscussions = ref(false)
const editor = ref(null) const editor = ref(null)
@@ -297,14 +301,14 @@ const breadcrumbs = computed(() => {
let items = [{ label: 'All Courses', route: { name: 'Courses' } }] let items = [{ label: 'All Courses', route: { name: 'Courses' } }]
items.push({ items.push({
label: lesson?.data?.course_title, label: lesson?.data?.course_title,
route: { name: 'CourseDetail', params: { courseName: props.courseName } }, route: { name: 'CourseDetail', params: { course: props.courseName } },
}) })
items.push({ items.push({
label: lesson?.data?.title, label: lesson?.data?.title,
route: { route: {
name: 'Lesson', name: 'Lesson',
params: { params: {
courseName: props.courseName, course: props.courseName,
chapterNumber: props.chapterNumber, chapterNumber: props.chapterNumber,
lessonNumber: props.lessonNumber, lessonNumber: props.lessonNumber,
}, },
@@ -375,30 +379,6 @@ const allowInstructorContent = () => {
return false return false
} }
const enrollment = createResource({
url: 'frappe.client.insert',
makeParams() {
return {
doc: {
doctype: 'LMS Enrollment',
course: props.courseName,
member: user.data?.name,
},
}
},
})
const enrollStudent = () => {
enrollment.submit(
{},
{
onSuccess() {
window.location.reload()
},
}
)
}
const redirectToLogin = () => { const redirectToLogin = () => {
window.location.href = `/login?redirect-to=/lms/courses/${props.courseName}` window.location.href = `/login?redirect-to=/lms/courses/${props.courseName}`
} }

View File

@@ -69,7 +69,7 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import { Breadcrumbs, Button, createResource, FormControl } from 'frappe-ui' import { Breadcrumbs, FormControl, createResource, Button } from 'frappe-ui'
import { import {
computed, computed,
reactive, reactive,

View File

@@ -57,15 +57,6 @@ export function formatNumberIntoCurrency(number, currency) {
return '' return ''
} }
// create a function that formats numbers in thousands to k
export function formatAmount(amount) {
if (amount > 999) {
return (amount / 1000).toFixed(1) + 'k'
}
return amount
}
export function convertToTitleCase(str) { export function convertToTitleCase(str) {
if (!str) { if (!str) {
return '' return ''

View File

@@ -51,7 +51,7 @@ export class Quiz {
app.mount(this.wrapper) app.mount(this.wrapper)
return return
} }
this.wrapper.innerHTML = `<div class='border rounded-md p-10 text-center bg-gray-50 mb-2'> this.wrapper.innerHTML = `<div class='border rounded-md p-10 text-center mb-2'>
<span class="font-medium"> <span class="font-medium">
Quiz: ${quiz} Quiz: ${quiz}
</span> </span>

View File

@@ -1224,10 +1224,10 @@ fraction.js@^4.3.7:
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7" resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
frappe-ui@^0.1.72: frappe-ui@^0.1.69:
version "0.1.72" version "0.1.69"
resolved "https://registry.yarnpkg.com/frappe-ui/-/frappe-ui-0.1.72.tgz#f5550056ddee7ad4341f2c1825d046404d221820" resolved "https://registry.yarnpkg.com/frappe-ui/-/frappe-ui-0.1.69.tgz#bfc6d19dff97d2666c36da63f5de62f819539406"
integrity sha512-XWYKmCjw3ViD+/+tZMUiYqwHFlMGMsVuazOYiN5bKlE+aiheJsnHlOOUyQswYX1Y7jNxuC7gGpSLNg2ZpXA7hA== integrity sha512-MKHYTcRvmccZwTYlIcmf4OCbJQH5eqKXsq3Cj2lbnmoWuuTh9m7T3AoRKEwOIlZ0mSGCH9yzaF2BINBXGpIJdQ==
dependencies: dependencies:
"@headlessui/vue" "^1.7.14" "@headlessui/vue" "^1.7.14"
"@popperjs/core" "^2.11.2" "@popperjs/core" "^2.11.2"

View File

@@ -1 +1 @@
__version__ = "2.10.0" __version__ = "2.9.0"

View File

@@ -110,8 +110,7 @@ doc_events = {
# --------------- # ---------------
scheduler_events = { scheduler_events = {
"hourly": [ "hourly": [
"lms.lms.doctype.lms_certificate_request.lms_certificate_request.schedule_evals", "lms.lms.doctype.lms_certificate_request.lms_certificate_request.schedule_evals"
"lms.lms.api.update_course_statistics",
], ],
"daily": ["lms.job.doctype.job_opportunity.job_opportunity.update_job_openings"], "daily": ["lms.job.doctype.job_opportunity.job_opportunity.update_job_openings"],
} }

View File

@@ -6,9 +6,8 @@ from frappe.translate import get_all_translations
from frappe import _ from frappe import _
from frappe.query_builder import DocType from frappe.query_builder import DocType
from frappe.query_builder.functions import Count from frappe.query_builder.functions import Count
from frappe.utils import time_diff, now_datetime, get_datetime, flt from frappe.utils import time_diff, now_datetime, get_datetime
from typing import Optional from typing import Optional
from lms.lms.utils import get_average_rating, get_lesson_count
@frappe.whitelist() @frappe.whitelist()
@@ -761,44 +760,3 @@ def get_payment_gateway_details(payment_gateway):
"doctype": doctype, "doctype": doctype,
"docname": docname, "docname": docname,
} }
def update_course_statistics():
courses = frappe.get_all("LMS Course", fields=["name"])
for course in courses:
lessons = get_lesson_count(course.name)
enrollments = frappe.db.count(
"LMS Enrollment", {"course": course.name, "member_type": "Student"}
)
avg_rating = get_average_rating(course.name) or 0
avg_rating = flt(avg_rating, frappe.get_system_settings("float_precision") or 3)
frappe.db.set_value(
"LMS Course",
course.name,
{"lessons": lessons, "enrollments": enrollments, "rating": avg_rating},
)
@frappe.whitelist()
def get_announcements(batch):
return frappe.get_all(
"Communication",
filters={
"reference_doctype": "LMS Batch",
"reference_name": batch,
},
fields=[
"subject",
"content",
"recipients",
"cc",
"communication_date",
"sender",
"sender_full_name",
],
order_by="communication_date desc",
)

View File

@@ -7,3 +7,17 @@ from frappe.model.document import Document
class BatchStudent(Document): class BatchStudent(Document):
pass pass
@frappe.whitelist()
def enroll_batch(batch_name):
if frappe.db.exists(
"Batch Student", {"student": frappe.session.user, "parent": batch_name}
):
frappe.throw("You are already enrolled in this batch")
enrollment = frappe.new_doc("Batch Student")
enrollment.student = frappe.session.user
enrollment.parent = batch_name
enrollment.parentfield = "students"
enrollment.parenttype = "LMS Batch"
enrollment.save(ignore_permissions=True)

View File

@@ -9,8 +9,9 @@
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [ "field_order": [
"course", "course",
"column_break_3",
"title", "title",
"column_break_3",
"description",
"section_break_5", "section_break_5",
"lessons" "lessons"
], ],
@@ -34,6 +35,11 @@
"fieldname": "column_break_3", "fieldname": "column_break_3",
"fieldtype": "Column Break" "fieldtype": "Column Break"
}, },
{
"fieldname": "description",
"fieldtype": "Small Text",
"label": "Description"
},
{ {
"fieldname": "section_break_5", "fieldname": "section_break_5",
"fieldtype": "Section Break" "fieldtype": "Section Break"
@@ -53,7 +59,7 @@
"link_fieldname": "chapter" "link_fieldname": "chapter"
} }
], ],
"modified": "2024-10-29 16:54:20.904683", "modified": "2023-09-29 17:03:58.013819",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "LMS", "module": "LMS",
"name": "Course Chapter", "name": "Course Chapter",

View File

@@ -33,7 +33,6 @@ class LMSBatch(Document):
self.validate_timetable() self.validate_timetable()
self.send_confirmation_mail() self.send_confirmation_mail()
self.validate_evaluation_end_date() self.validate_evaluation_end_date()
self.add_students_to_live_class()
def validate_batch_end_date(self): def validate_batch_end_date(self):
if self.end_date < self.start_date: if self.end_date < self.start_date:
@@ -140,27 +139,6 @@ class LMSBatch(Document):
if cint(self.seat_count) < len(self.students): if cint(self.seat_count) < len(self.students):
frappe.throw(_("There are no seats available in this batch.")) frappe.throw(_("There are no seats available in this batch."))
def add_students_to_live_class(self):
for student in self.students:
if student.is_new():
live_classes = frappe.get_all(
"LMS Live Class", {"batch_name": self.name}, ["name", "event"]
)
for live_class in live_classes:
if live_class.event:
frappe.get_doc(
{
"doctype": "Event Participants",
"reference_doctype": "User",
"reference_docname": student.student,
"email": student.student,
"parent": live_class.event,
"parenttype": "Event",
"parentfield": "event_participants",
}
).save()
def validate_timetable(self): def validate_timetable(self):
for schedule in self.timetable: for schedule in self.timetable:
if schedule.start_time and schedule.end_time: if schedule.start_time and schedule.end_time:

View File

@@ -48,12 +48,7 @@
"certification_section", "certification_section",
"enable_certification", "enable_certification",
"column_break_rxww", "column_break_rxww",
"expiry", "expiry"
"tab_4_tab",
"statistics_section",
"enrollments",
"lessons",
"rating"
], ],
"fields": [ "fields": [
{ {
@@ -254,36 +249,6 @@
"fieldtype": "Link", "fieldtype": "Link",
"label": "Category", "label": "Category",
"options": "LMS Category" "options": "LMS Category"
},
{
"fieldname": "tab_4_tab",
"fieldtype": "Tab Break",
"label": "Statistics"
},
{
"fieldname": "statistics_section",
"fieldtype": "Section Break"
},
{
"default": "0",
"fieldname": "enrollments",
"fieldtype": "Data",
"label": "Enrollments",
"read_only": 1
},
{
"default": "0",
"fieldname": "lessons",
"fieldtype": "Data",
"label": "Lessons",
"read_only": 1
},
{
"default": "0",
"fieldname": "rating",
"fieldtype": "Data",
"label": "Rating",
"read_only": 1
} }
], ],
"is_published_field": "published", "is_published_field": "published",
@@ -310,7 +275,7 @@
} }
], ],
"make_attachments_public": 1, "make_attachments_public": 1,
"modified": "2024-10-30 23:08:31.842860", "modified": "2024-09-21 10:23:58.633912",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "LMS", "module": "LMS",
"name": "LMS Course", "name": "LMS Course",

View File

@@ -187,3 +187,192 @@ def reindex_exercises(doc):
course = frappe.get_doc("LMS Course", course_data["name"]) course = frappe.get_doc("LMS Course", course_data["name"])
course.reindex_exercises() course.reindex_exercises()
frappe.msgprint("All exercises in this course have been re-indexed.") frappe.msgprint("All exercises in this course have been re-indexed.")
@frappe.whitelist(allow_guest=True)
def search_course(text):
courses = frappe.get_all(
"LMS Course",
filters={"published": True},
or_filters={
"title": ["like", f"%{text}%"],
"tags": ["like", f"%{text}%"],
"short_introduction": ["like", f"%{text}%"],
"description": ["like", f"%{text}%"],
},
fields=["name", "title"],
)
return courses
@frappe.whitelist()
def submit_for_review(course):
chapters = frappe.get_all("Chapter Reference", {"parent": course})
if not len(chapters):
return "No Chp"
frappe.db.set_value("LMS Course", course, "status", "Under Review")
return "OK"
@frappe.whitelist()
def save_course(
tags,
title,
short_introduction,
video_link,
description,
course,
published,
upcoming,
image=None,
paid_course=False,
course_price=None,
currency=None,
):
if not can_create_courses(course):
return
if course:
doc = frappe.get_doc("LMS Course", course)
else:
doc = frappe.get_doc({"doctype": "LMS Course"})
doc.update(
{
"title": title,
"short_introduction": short_introduction,
"video_link": video_link,
"image": image,
"description": description,
"tags": tags,
"published": cint(published),
"upcoming": cint(upcoming),
"paid_course": cint(paid_course),
"course_price": course_price,
"currency": currency,
}
)
doc.save(ignore_permissions=True)
return doc.name
@frappe.whitelist()
def save_chapter(course, title, chapter_description, idx, chapter):
if chapter:
doc = frappe.get_doc("Course Chapter", chapter)
else:
doc = frappe.get_doc({"doctype": "Course Chapter"})
doc.update({"course": course, "title": title, "description": chapter_description})
doc.save(ignore_permissions=True)
if chapter:
chapter_reference = frappe.get_doc("Chapter Reference", {"chapter": chapter})
else:
chapter_reference = frappe.get_doc(
{
"doctype": "Chapter Reference",
"parent": course,
"parenttype": "LMS Course",
"parentfield": "chapters",
"idx": idx,
}
)
chapter_reference.update({"chapter": doc.name})
chapter_reference.save(ignore_permissions=True)
return doc.name
@frappe.whitelist()
def save_lesson(
title,
body,
chapter,
preview,
idx,
lesson,
instructor_notes=None,
youtube=None,
quiz_id=None,
question=None,
file_type=None,
):
if lesson:
doc = frappe.get_doc("Course Lesson", lesson)
else:
doc = frappe.get_doc({"doctype": "Course Lesson"})
doc.update(
{
"chapter": chapter,
"title": title,
"body": body,
"instructor_notes": instructor_notes,
"include_in_preview": preview,
"youtube": youtube,
"quiz_id": quiz_id,
"question": question,
"file_type": file_type,
}
)
doc.save(ignore_permissions=True)
if lesson:
lesson_reference = frappe.get_doc("Lesson Reference", {"lesson": lesson})
else:
lesson_reference = frappe.get_doc(
{
"doctype": "Lesson Reference",
"parent": chapter,
"parenttype": "Course Chapter",
"parentfield": "lessons",
"idx": idx,
}
)
lesson_reference.update({"lesson": doc.name})
lesson_reference.save(ignore_permissions=True)
return doc.name
@frappe.whitelist()
def reorder_lesson(old_chapter, old_lesson_array, new_chapter, new_lesson_array):
if old_chapter == new_chapter:
sort_lessons(new_chapter, new_lesson_array)
else:
sort_lessons(old_chapter, old_lesson_array)
sort_lessons(new_chapter, new_lesson_array)
def sort_lessons(chapter, lesson_array):
lesson_array = json.loads(lesson_array)
for les in lesson_array:
ref = frappe.get_all("Lesson Reference", {"lesson": les}, ["name", "idx"])
if ref:
frappe.db.set_value(
"Lesson Reference",
ref[0].name,
{
"parent": chapter,
"idx": lesson_array.index(les) + 1,
},
)
@frappe.whitelist()
def reorder_chapter(chapter_array):
chapter_array = json.loads(chapter_array)
for chap in chapter_array:
ref = frappe.get_all("Chapter Reference", {"chapter": chap}, ["name", "idx"])
if ref:
frappe.db.set_value(
"Chapter Reference",
ref[0].name,
{
"idx": chapter_array.index(chap) + 1,
},
)

View File

@@ -75,8 +75,7 @@
"in_standard_filter": 1, "in_standard_filter": 1,
"label": "Course", "label": "Course",
"options": "LMS Course", "options": "LMS Course",
"reqd": 1, "reqd": 1
"search_index": 1
}, },
{ {
"fieldname": "current_lesson", "fieldname": "current_lesson",
@@ -127,7 +126,7 @@
], ],
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"links": [], "links": [],
"modified": "2024-10-30 12:44:16.103598", "modified": "2024-05-14 14:50:08.405033",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "LMS", "module": "LMS",
"name": "LMS Enrollment", "name": "LMS Enrollment",

View File

@@ -10,20 +10,19 @@
"title", "title",
"host", "host",
"batch_name", "batch_name",
"event",
"column_break_astv", "column_break_astv",
"description",
"section_break_glxh",
"date", "date",
"duration",
"column_break_spvt",
"time", "time",
"duration",
"section_break_glxh",
"description",
"column_break_spvt",
"timezone", "timezone",
"section_break_yrpq",
"password", "password",
"auto_recording",
"section_break_yrpq",
"start_url", "start_url",
"column_break_yokr", "column_break_yokr",
"auto_recording",
"join_url" "join_url"
], ],
"fields": [ "fields": [
@@ -123,18 +122,11 @@
"fieldtype": "Select", "fieldtype": "Select",
"label": "Auto Recording", "label": "Auto Recording",
"options": "No Recording\nLocal\nCloud" "options": "No Recording\nLocal\nCloud"
},
{
"fieldname": "event",
"fieldtype": "Link",
"label": "Event",
"options": "Event",
"read_only": 1
} }
], ],
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"links": [], "links": [],
"modified": "2024-10-31 15:41:35.540856", "modified": "2024-01-09 11:22:33.272341",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "LMS", "module": "LMS",
"name": "LMS Live Class", "name": "LMS Live Class",

View File

@@ -16,7 +16,6 @@ class LMSLiveClass(Document):
if calendar: if calendar:
event = self.create_event() event = self.create_event()
self.add_event_participants(event, calendar) self.add_event_participants(event, calendar)
frappe.db.set_value(self.doctype, self.name, "event", event.name)
def create_event(self): def create_event(self):
start = f"{self.date} {self.time}" start = f"{self.date} {self.time}"

View File

@@ -76,7 +76,6 @@
"default": "0", "default": "0",
"fieldname": "payment_received", "fieldname": "payment_received",
"fieldtype": "Check", "fieldtype": "Check",
"in_standard_filter": 1,
"label": "Payment Received" "label": "Payment Received"
}, },
{ {
@@ -141,7 +140,7 @@
], ],
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"links": [], "links": [],
"modified": "2024-10-31 15:33:39.420366", "modified": "2023-10-26 16:54:12.408274",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "LMS", "module": "LMS",
"name": "LMS Payment", "name": "LMS Payment",

View File

@@ -86,32 +86,32 @@ def get_charts(data):
completed = 0 completed = 0
less_than_hundred = 0 less_than_hundred = 0
less_than_seventy_one = 0 less_than_seventy = 0
less_than_forty_one = 0 less_than_forty = 0
less_than_eleven = 0 less_than_ten = 0
for row in data: for row in data:
if row.progress == 100: if row.progress == 100:
completed += 1 completed += 1
elif row.progress < 100 and row.progress > 70: elif row.progress < 100 and row.progress > 70:
less_than_hundred += 1 less_than_hundred += 1
elif row.progress < 71 and row.progress > 40: elif row.progress < 70 and row.progress > 40:
less_than_seventy_one += 1 less_than_seventy += 1
elif row.progress < 41 and row.progress > 10: elif row.progress < 40 and row.progress > 10:
less_than_forty_one += 1 less_than_forty += 1
elif row.progress < 11: elif row.progress < 10:
less_than_eleven += 1 less_than_ten += 1
charts = { charts = {
"data": { "data": {
"labels": ["0-10", "11-40", "41-70", "71-99", "100"], "labels": ["0-10", "10-40", "40-70", "70-99", "100"],
"datasets": [ "datasets": [
{ {
"name": "Progress (%)", "name": "Progress (%)",
"values": [ "values": [
less_than_eleven, less_than_ten,
less_than_forty_one, less_than_forty,
less_than_seventy_one, less_than_seventy,
less_than_hundred, less_than_hundred,
completed, completed,
], ],

View File

@@ -109,7 +109,7 @@ def get_chapters(course):
chapter_details = frappe.db.get_value( chapter_details = frappe.db.get_value(
"Course Chapter", "Course Chapter",
{"name": chapter.chapter}, {"name": chapter.chapter},
["name", "title"], ["name", "title", "description"],
as_dict=True, as_dict=True,
) )
chapter.update(chapter_details) chapter.update(chapter_details)
@@ -157,12 +157,11 @@ def get_lesson_details(chapter, progress=False):
"file_type", "file_type",
"instructor_notes", "instructor_notes",
"course", "course",
"content",
], ],
as_dict=True, as_dict=True,
) )
lesson_details.number = f"{chapter.idx}.{row.idx}" lesson_details.number = f"{chapter.idx}.{row.idx}"
lesson_details.icon = get_lesson_icon(lesson_details.body, lesson_details.content) lesson_details.icon = get_lesson_icon(lesson_details.body)
if progress: if progress:
lesson_details.is_complete = get_progress(lesson_details.course, lesson_details.name) lesson_details.is_complete = get_progress(lesson_details.course, lesson_details.name)
@@ -171,38 +170,20 @@ def get_lesson_details(chapter, progress=False):
return lessons return lessons
def get_lesson_icon(body, content): def get_lesson_icon(content):
if content: icon = None
content = json.loads(content) macros = find_macros(content)
for block in content.get("blocks"):
if block.get("type") == "upload" and block.get("data").get("file_type").lower() in [
"mp4",
"webm",
"ogg",
"mov",
]:
return "icon-youtube"
if block.get("type") == "embed" and block.get("data").get("service") in [
"youtube",
"vimeo",
]:
return "icon-youtube"
if block.get("type") == "quiz":
return "icon-quiz"
return "icon-list"
macros = find_macros(body)
for macro in macros: for macro in macros:
if macro[0] == "YouTubeVideo" or macro[0] == "Video": if macro[0] == "YouTubeVideo" or macro[0] == "Video":
return "icon-youtube" icon = "icon-youtube"
elif macro[0] == "Quiz": elif macro[0] == "Quiz":
return "icon-quiz" icon = "icon-quiz"
return "icon-list" if not icon:
icon = "icon-list"
return icon
@frappe.whitelist(allow_guest=True) @frappe.whitelist(allow_guest=True)
@@ -1046,13 +1027,23 @@ def get_course_details(course):
"currency", "currency",
"amount_usd", "amount_usd",
"enable_certification", "enable_certification",
"lessons",
"enrollments",
"rating",
], ],
as_dict=1, as_dict=1,
) )
course_details.tags = course_details.tags.split(",") if course_details.tags else [] course_details.tags = course_details.tags.split(",") if course_details.tags else []
course_details.lesson_count = get_lesson_count(course_details.name)
course_details.enrollment_count = frappe.db.count(
"LMS Enrollment", {"course": course_details.name, "member_type": "Student"}
)
course_details.enrollment_count_formatted = format_number(
course_details.enrollment_count
)
avg_rating = get_average_rating(course_details.name) or 0
course_details.avg_rating = flt(
avg_rating, frappe.get_system_settings("float_precision") or 3
)
course_details.instructors = get_instructors(course_details.name) course_details.instructors = get_instructors(course_details.name)
if course_details.paid_course: if course_details.paid_course:
@@ -1101,14 +1092,14 @@ def get_categorized_courses(courses):
): ):
new.append(course) new.append(course)
if course.membership: if course.membership and course.published:
enrolled.append(course) enrolled.append(course)
elif course.is_instructor: elif course.is_instructor:
created.append(course) created.append(course)
categories = [live, enrolled, created] categories = [live, enrolled, created]
for category in categories: for category in categories:
category.sort(key=lambda x: x.enrollments, reverse=True) category.sort(key=lambda x: x.enrollment_count, reverse=True)
live.sort(key=lambda x: x.featured, reverse=True) live.sort(key=lambda x: x.featured, reverse=True)
@@ -1133,7 +1124,7 @@ def get_course_outline(course, progress=False):
chapter_details = frappe.db.get_value( chapter_details = frappe.db.get_value(
"Course Chapter", "Course Chapter",
chapter.chapter, chapter.chapter,
["name", "title"], ["name", "title", "description"],
as_dict=True, as_dict=True,
) )
chapter_details["idx"] = chapter.idx chapter_details["idx"] = chapter.idx

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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-01 16:04+0000\n" "POT-Creation-Date: 2024-10-25 10:37+0000\n"
"PO-Revision-Date: 2024-11-01 16:04+0000\n" "PO-Revision-Date: 2024-10-25 10:37+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"
@@ -60,10 +60,6 @@ msgstr ""
msgid "<span style=\"font-size: 18px;\"><b>Statistics</b></span>" msgid "<span style=\"font-size: 18px;\"><b>Statistics</b></span>"
msgstr "" msgstr ""
#: frontend/src/pages/CourseForm.vue:32
msgid "A one line introduction to the course that appears on the course card"
msgstr ""
#: frontend/src/pages/ProfileAbout.vue:4 #: frontend/src/pages/ProfileAbout.vue:4
msgid "About" msgid "About"
msgstr "" msgstr ""
@@ -104,6 +100,7 @@ msgstr ""
#: frontend/src/components/CourseOutline.vue:11 #: frontend/src/components/CourseOutline.vue:11
#: frontend/src/components/CreateOutline.vue:18 #: frontend/src/components/CreateOutline.vue:18
#: frontend/src/components/Modals/ChapterModal.vue:5 #: frontend/src/components/Modals/ChapterModal.vue:5
#: frontend/src/components/Modals/ChapterModal.vue:9
msgid "Add Chapter" msgid "Add Chapter"
msgstr "" msgstr ""
@@ -226,7 +223,7 @@ msgstr ""
#. Label of the amount (Currency) field in DocType 'Web Form' #. Label of the amount (Currency) field in DocType 'Web Form'
#. Label of the amount (Currency) field in DocType 'LMS Batch' #. Label of the amount (Currency) field in DocType 'LMS Batch'
#. Label of the amount (Currency) field in DocType 'LMS Payment' #. Label of the amount (Currency) field in DocType 'LMS Payment'
#: frontend/src/pages/BatchForm.vue:208 lms/fixtures/custom_field.json #: frontend/src/pages/BatchForm.vue:198 lms/fixtures/custom_field.json
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/lms/doctype/lms_payment/lms_payment.json #: lms/lms/doctype/lms_payment/lms_payment.json
#: lms/public/js/common_functions.js:379 #: lms/public/js/common_functions.js:379
@@ -270,14 +267,6 @@ msgstr ""
msgid "Answer" msgid "Answer"
msgstr "" msgstr ""
#: frontend/src/pages/CourseForm.vue:76 frontend/src/pages/CourseForm.vue:94
msgid "Appears on the course card in the course list"
msgstr ""
#: frontend/src/pages/BatchForm.vue:55 frontend/src/pages/BatchForm.vue:73
msgid "Appears when the batch URL is shared on any online platform"
msgstr ""
#: frontend/src/pages/JobDetail.vue:131 #: frontend/src/pages/JobDetail.vue:131
msgid "Applications Received" msgid "Applications Received"
msgstr "" msgstr ""
@@ -476,7 +465,7 @@ msgid "Batch Description"
msgstr "" msgstr ""
#. Label of the batch_details (Text Editor) field in DocType 'LMS Batch' #. Label of the batch_details (Text Editor) field in DocType 'LMS Batch'
#: frontend/src/pages/BatchForm.vue:97 lms/lms/doctype/lms_batch/lms_batch.json #: frontend/src/pages/BatchForm.vue:89 lms/lms/doctype/lms_batch/lms_batch.json
#: lms/public/js/common_functions.js:349 #: lms/public/js/common_functions.js:349
#: lms/templates/emails/batch_confirmation.html:30 #: lms/templates/emails/batch_confirmation.html:30
msgid "Batch Details" msgid "Batch Details"
@@ -643,8 +632,8 @@ msgstr ""
#. Label of the category (Link) field in DocType 'LMS Batch' #. Label of the category (Link) field in DocType 'LMS Batch'
#. Label of the category (Data) field in DocType 'LMS Category' #. Label of the category (Data) field in DocType 'LMS Category'
#. Label of the category (Link) field in DocType 'LMS Course' #. Label of the category (Link) field in DocType 'LMS Course'
#: frontend/src/pages/BatchForm.vue:189 frontend/src/pages/Batches.vue:16 #: frontend/src/pages/BatchForm.vue:179 frontend/src/pages/Batches.vue:16
#: frontend/src/pages/CourseForm.vue:139 frontend/src/pages/Courses.vue:17 #: frontend/src/pages/CourseForm.vue:116 frontend/src/pages/Courses.vue:17
#: frontend/src/pages/JobDetail.vue:102 #: frontend/src/pages/JobDetail.vue:102
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/lms/doctype/lms_category/lms_category.json #: lms/lms/doctype/lms_category/lms_category.json
@@ -945,7 +934,7 @@ msgstr ""
msgid "Completed" msgid "Completed"
msgstr "" msgstr ""
#: frontend/src/pages/CourseForm.vue:192 #: frontend/src/pages/CourseForm.vue:168
msgid "Completion Certificate" msgid "Completion Certificate"
msgstr "" msgstr ""
@@ -995,7 +984,7 @@ msgstr ""
msgid "Contract" msgid "Contract"
msgstr "" msgstr ""
#: lms/lms/utils.py:442 #: lms/lms/utils.py:423
msgid "Cookie Policy" msgid "Cookie Policy"
msgstr "" msgstr ""
@@ -1116,7 +1105,7 @@ msgstr ""
msgid "Course Data" msgid "Course Data"
msgstr "" msgstr ""
#: frontend/src/pages/CourseForm.vue:41 #: frontend/src/pages/CourseForm.vue:34
msgid "Course Description" msgid "Course Description"
msgstr "" msgstr ""
@@ -1125,7 +1114,7 @@ msgstr ""
msgid "Course Evaluator" msgid "Course Evaluator"
msgstr "" msgstr ""
#: frontend/src/pages/CourseForm.vue:54 #: frontend/src/pages/CourseForm.vue:64
msgid "Course Image" msgid "Course Image"
msgstr "" msgstr ""
@@ -1148,7 +1137,7 @@ msgid "Course Name"
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:210 #: frontend/src/pages/CourseForm.vue:186
#: lms/lms/doctype/lms_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
msgid "Course Price" msgid "Course Price"
msgstr "" msgstr ""
@@ -1181,7 +1170,7 @@ msgstr ""
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:433
msgid "Course price and currency are mandatory for paid courses" msgid "Course price and currency are mandatory for paid courses"
msgstr "" msgstr ""
@@ -1219,10 +1208,6 @@ msgstr ""
msgid "Cover Image" msgid "Cover Image"
msgstr "" msgstr ""
#: frontend/src/components/Modals/ChapterModal.vue:9
msgid "Create"
msgstr ""
#: lms/lms/doctype/lms_certificate_evaluation/lms_certificate_evaluation.js:7 #: lms/lms/doctype/lms_certificate_evaluation/lms_certificate_evaluation.js:7
msgid "Create LMS Certificate" msgid "Create LMS Certificate"
msgstr "" msgstr ""
@@ -1231,11 +1216,7 @@ msgstr ""
msgid "Create LMS Certificate Evaluation" msgid "Create LMS Certificate Evaluation"
msgstr "" msgstr ""
#: frontend/src/pages/Batches.vue:110 #: lms/templates/onboarding_header.html:19
msgid "Create a Batch"
msgstr ""
#: frontend/src/pages/Courses.vue:131 lms/templates/onboarding_header.html:19
msgid "Create a Course" msgid "Create a Course"
msgstr "" msgstr ""
@@ -1251,7 +1232,7 @@ msgstr ""
#. Label of the currency (Link) field in DocType 'LMS Batch' #. Label of the currency (Link) field in DocType 'LMS Batch'
#. Label of the currency (Link) field in DocType 'LMS Course' #. Label of the currency (Link) field in DocType 'LMS Course'
#. Label of the currency (Link) field in DocType 'LMS Payment' #. Label of the currency (Link) field in DocType 'LMS Payment'
#: frontend/src/pages/BatchForm.vue:216 frontend/src/pages/CourseForm.vue:217 #: frontend/src/pages/BatchForm.vue:206 frontend/src/pages/CourseForm.vue:193
#: lms/fixtures/custom_field.json lms/lms/doctype/lms_batch/lms_batch.json #: lms/fixtures/custom_field.json lms/lms/doctype/lms_batch/lms_batch.json
#: lms/lms/doctype/lms_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
#: lms/lms/doctype/lms_payment/lms_payment.json #: lms/lms/doctype/lms_payment/lms_payment.json
@@ -1309,7 +1290,7 @@ msgstr ""
#. Label of the section_break_glxh (Section Break) field in DocType 'LMS Live #. Label of the section_break_glxh (Section Break) field in DocType 'LMS Live
#. Class' #. Class'
#: frontend/src/pages/BatchForm.vue:110 #: frontend/src/pages/BatchForm.vue:102
#: lms/lms/doctype/lms_live_class/lms_live_class.json #: lms/lms/doctype/lms_live_class/lms_live_class.json
msgid "Date and Time" msgid "Date and Time"
msgstr "" msgstr ""
@@ -1357,6 +1338,7 @@ msgstr ""
#. Label of the description (Markdown Editor) field in DocType 'Cohort' #. Label of the description (Markdown Editor) field in DocType 'Cohort'
#. Label of the description (Markdown Editor) field in DocType 'Cohort #. Label of the description (Markdown Editor) field in DocType 'Cohort
#. Subgroup' #. Subgroup'
#. Label of the description (Small Text) field in DocType 'Course Chapter'
#. Label of the description (Small Text) field in DocType 'LMS Badge' #. Label of the description (Small Text) field in DocType 'LMS Badge'
#. Label of the description (Small Text) field in DocType 'LMS Batch' #. Label of the description (Small Text) field in DocType 'LMS Batch'
#. Label of the description (Markdown Editor) field in DocType 'LMS Batch Old' #. Label of the description (Markdown Editor) field in DocType 'LMS Batch Old'
@@ -1365,11 +1347,12 @@ msgstr ""
#. Label of the description (Text) field in DocType 'LMS Live Class' #. Label of the description (Text) field in DocType 'LMS Live Class'
#. Label of the description (Small Text) field in DocType 'Work Experience' #. Label of the description (Small Text) field in DocType 'Work Experience'
#: frontend/src/components/Modals/LiveClassModal.vue:73 #: frontend/src/components/Modals/LiveClassModal.vue:73
#: frontend/src/pages/BatchForm.vue:90 frontend/src/pages/JobCreation.vue:43 #: frontend/src/pages/BatchForm.vue:83 frontend/src/pages/JobCreation.vue:43
#: lms/job/doctype/job_opportunity/job_opportunity.json #: lms/job/doctype/job_opportunity/job_opportunity.json
#: lms/lms/doctype/certification/certification.json #: lms/lms/doctype/certification/certification.json
#: lms/lms/doctype/cohort/cohort.json #: 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/course_chapter/course_chapter.json
#: lms/lms/doctype/lms_badge/lms_badge.json #: lms/lms/doctype/lms_badge/lms_badge.json
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/lms/doctype/lms_batch_old/lms_batch_old.json #: lms/lms/doctype/lms_batch_old/lms_batch_old.json
@@ -1391,7 +1374,7 @@ msgstr ""
msgid "Details" msgid "Details"
msgstr "" msgstr ""
#: frontend/src/pages/CourseForm.vue:187 #: frontend/src/pages/CourseForm.vue:163
msgid "Disable Self Enrollment" msgid "Disable Self Enrollment"
msgstr "" msgstr ""
@@ -1466,14 +1449,13 @@ msgstr ""
#: frontend/src/components/BatchOverlay.vue:93 #: frontend/src/components/BatchOverlay.vue:93
#: frontend/src/components/CourseCardOverlay.vue:86 #: frontend/src/components/CourseCardOverlay.vue:86
#: frontend/src/components/Modals/ChapterModal.vue:9
#: frontend/src/pages/JobDetail.vue:31 frontend/src/pages/Lesson.vue:70 #: frontend/src/pages/JobDetail.vue:31 frontend/src/pages/Lesson.vue:70
#: frontend/src/pages/Profile.vue:32 #: frontend/src/pages/Profile.vue:32
msgid "Edit" msgid "Edit"
msgstr "" msgstr ""
#: frontend/src/components/CourseOutline.vue:106 #: frontend/src/components/CourseOutline.vue:106
#: frontend/src/components/Modals/ChapterModal.vue:5 #: frontend/src/components/Modals/ChapterModal.vue:9
msgid "Edit Chapter" msgid "Edit Chapter"
msgstr "" msgstr ""
@@ -1549,7 +1531,7 @@ msgstr ""
#. Label of the end_date (Date) field in DocType 'Cohort' #. Label of the end_date (Date) field in DocType 'Cohort'
#. Label of the end_date (Date) field in DocType 'LMS Batch' #. Label of the end_date (Date) field in DocType 'LMS Batch'
#: frontend/src/pages/BatchForm.vue:122 lms/lms/doctype/cohort/cohort.json #: frontend/src/pages/BatchForm.vue:114 lms/lms/doctype/cohort/cohort.json
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/public/js/common_functions.js:282 #: lms/public/js/common_functions.js:282
msgid "End Date" msgid "End Date"
@@ -1567,7 +1549,7 @@ msgstr ""
#. Label of the end_time (Time) field in DocType 'LMS Certificate Evaluation' #. Label of the end_time (Time) field in DocType 'LMS Certificate Evaluation'
#. Label of the end_time (Time) field in DocType 'LMS Certificate Request' #. Label of the end_time (Time) field in DocType 'LMS Certificate Request'
#. Label of the end_time (Time) field in DocType 'Scheduled Flow' #. Label of the end_time (Time) field in DocType 'Scheduled Flow'
#: frontend/src/pages/BatchForm.vue:136 #: frontend/src/pages/BatchForm.vue:128
#: frontend/src/pages/ProfileEvaluator.vue:18 #: frontend/src/pages/ProfileEvaluator.vue:18
#: lms/lms/doctype/evaluator_schedule/evaluator_schedule.json #: lms/lms/doctype/evaluator_schedule/evaluator_schedule.json
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
@@ -1603,15 +1585,13 @@ msgstr ""
msgid "Enrollment Count" msgid "Enrollment Count"
msgstr "" msgstr ""
#: lms/lms/utils.py:1692 #: lms/lms/utils.py:1683
msgid "Enrollment Failed" msgid "Enrollment Failed"
msgstr "" msgstr ""
#. Label of the enrollments (Data) field in DocType 'LMS Course'
#. Label of a chart in the LMS Workspace #. Label of a chart in the LMS Workspace
#. Label of a shortcut in the LMS Workspace #. Label of a shortcut in the LMS Workspace
#: frontend/src/pages/Statistics.vue:45 #: frontend/src/pages/Statistics.vue:45 lms/lms/workspace/lms/lms.json
#: lms/lms/doctype/lms_course/lms_course.json lms/lms/workspace/lms/lms.json
msgid "Enrollments" msgid "Enrollments"
msgstr "" msgstr ""
@@ -1653,7 +1633,7 @@ msgid "Evaluation Details"
msgstr "" msgstr ""
#. Label of the evaluation_end_date (Date) field in DocType 'LMS Batch' #. Label of the evaluation_end_date (Date) field in DocType 'LMS Batch'
#: frontend/src/pages/BatchForm.vue:165 #: frontend/src/pages/BatchForm.vue:155
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/public/js/common_functions.js:333 #: lms/public/js/common_functions.js:333
msgid "Evaluation End Date" msgid "Evaluation End Date"
@@ -1715,10 +1695,6 @@ msgstr ""
msgid "Event" msgid "Event"
msgstr "" msgstr ""
#: frontend/src/pages/BatchForm.vue:144
msgid "Example: IST (+5:30)"
msgstr ""
#. 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'
#: lms/lms/doctype/exercise_latest_submission/exercise_latest_submission.json #: lms/lms/doctype/exercise_latest_submission/exercise_latest_submission.json
@@ -1789,7 +1765,7 @@ msgstr ""
#. Label of the featured (Check) field in DocType 'LMS Course' #. Label of the featured (Check) field in DocType 'LMS Course'
#: frontend/src/components/CourseCard.vue:16 #: frontend/src/components/CourseCard.vue:16
#: frontend/src/pages/CourseForm.vue:180 #: frontend/src/pages/CourseForm.vue:156
#: lms/lms/doctype/lms_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
msgid "Featured" msgid "Featured"
msgstr "" msgstr ""
@@ -2052,10 +2028,6 @@ msgstr ""
msgid "Icon" msgid "Icon"
msgstr "" msgstr ""
#: frontend/src/components/LessonHelp.vue:68
msgid "If Include in Preview is enabled for a lesson then the lesson will also be accessible to non logged in users."
msgstr ""
#: lms/templates/emails/mentor_request_creation_email.html:5 #: lms/templates/emails/mentor_request_creation_email.html:5
msgid "If you are not any more interested to mentor the course" msgid "If you are not any more interested to mentor the course"
msgstr "" msgstr ""
@@ -2192,7 +2164,7 @@ msgstr ""
#. Label of the instructors (Table MultiSelect) field in DocType 'LMS Batch' #. Label of the instructors (Table MultiSelect) field in DocType 'LMS Batch'
#. Label of the instructors (Table MultiSelect) field in DocType 'LMS Course' #. Label of the instructors (Table MultiSelect) field in DocType 'LMS Course'
#: frontend/src/pages/BatchForm.vue:85 frontend/src/pages/CourseForm.vue:146 #: frontend/src/pages/BatchForm.vue:77 frontend/src/pages/CourseForm.vue:123
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/lms/doctype/lms_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
msgid "Instructors" msgid "Instructors"
@@ -2351,10 +2323,6 @@ msgstr ""
msgid "Join URL" msgid "Join URL"
msgstr "" msgstr ""
#: frontend/src/pages/CourseForm.vue:128
msgid "Keywords for the course"
msgstr ""
#. Name of a Workspace #. Name of a Workspace
#: lms/lms/workspace/lms/lms.json #: lms/lms/workspace/lms/lms.json
msgid "LMS" msgid "LMS"
@@ -2608,11 +2576,9 @@ msgstr ""
#. Label of the lessons (Table) field in DocType 'Course Chapter' #. Label of the lessons (Table) field in DocType 'Course Chapter'
#. Group in Course Chapter's connections #. Group in Course Chapter's connections
#. Label of the lessons (Data) field in DocType 'LMS Course'
#: frontend/src/components/CourseCard.vue:34 #: frontend/src/components/CourseCard.vue:34
#: frontend/src/components/CourseCardOverlay.vue:96 #: frontend/src/components/CourseCardOverlay.vue:96
#: lms/lms/doctype/course_chapter/course_chapter.json #: lms/lms/doctype/course_chapter/course_chapter.json
#: lms/lms/doctype/lms_course/lms_course.json
msgid "Lessons" msgid "Lessons"
msgstr "" msgstr ""
@@ -2785,7 +2751,7 @@ msgid "Maximun Attempts"
msgstr "" msgstr ""
#. Label of the medium (Select) field in DocType 'LMS Batch' #. Label of the medium (Select) field in DocType 'LMS Batch'
#: frontend/src/pages/BatchForm.vue:184 #: frontend/src/pages/BatchForm.vue:174
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/public/js/common_functions.js:309 #: lms/public/js/common_functions.js:309
msgid "Medium" msgid "Medium"
@@ -2933,7 +2899,7 @@ msgid "Mentors"
msgstr "" msgstr ""
#. Label of the meta_image (Attach Image) field in DocType 'LMS Batch' #. Label of the meta_image (Attach Image) field in DocType 'LMS Batch'
#: frontend/src/pages/BatchForm.vue:36 lms/lms/doctype/lms_batch/lms_batch.json #: frontend/src/pages/BatchForm.vue:53 lms/lms/doctype/lms_batch/lms_batch.json
#: lms/public/js/common_functions.js:362 #: lms/public/js/common_functions.js:362
msgid "Meta Image" msgid "Meta Image"
msgstr "" msgstr ""
@@ -2969,11 +2935,11 @@ msgstr ""
msgid "Modified By" msgid "Modified By"
msgstr "" msgstr ""
#: lms/lms/api.py:191 #: lms/lms/api.py:190
msgid "Module Name is incorrect or does not exist." msgid "Module Name is incorrect or does not exist."
msgstr "" msgstr ""
#: lms/lms/api.py:187 #: lms/lms/api.py:186
msgid "Module is incorrect." msgid "Module is incorrect."
msgstr "" msgstr ""
@@ -3040,11 +3006,11 @@ msgstr ""
msgid "New Sign Up" msgid "New Sign Up"
msgstr "" msgstr ""
#: lms/lms/utils.py:632 #: lms/lms/utils.py:613
msgid "New comment in batch {0}" msgid "New comment in batch {0}"
msgstr "" msgstr ""
#: lms/lms/utils.py:625 #: lms/lms/utils.py:606
msgid "New reply on the topic {0} in course {1}" msgid "New reply on the topic {0} in course {1}"
msgstr "" msgstr ""
@@ -3082,10 +3048,6 @@ msgstr ""
msgid "No announcements" msgid "No announcements"
msgstr "" msgstr ""
#: frontend/src/pages/Batches.vue:125
msgid "No batches found"
msgstr ""
#: lms/templates/certificates_section.html:23 #: lms/templates/certificates_section.html:23
msgid "No certificates" msgid "No certificates"
msgstr "" msgstr ""
@@ -3094,10 +3056,6 @@ msgstr ""
msgid "No courses created" msgid "No courses created"
msgstr "" msgstr ""
#: frontend/src/pages/Courses.vue:146
msgid "No courses found"
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 ""
@@ -3126,12 +3084,12 @@ msgstr ""
msgid "No {0}" msgid "No {0}"
msgstr "" msgstr ""
#: frontend/src/pages/Batches.vue:84 #: frontend/src/pages/Batches.vue:88
msgid "No {0} batches" msgid "No {0} batches found"
msgstr "" msgstr ""
#: frontend/src/pages/Courses.vue:106 #: frontend/src/pages/Courses.vue:110
msgid "No {0} courses" msgid "No {0} courses found"
msgstr "" msgstr ""
#: lms/templates/quiz/quiz.html:147 #: lms/templates/quiz/quiz.html:147
@@ -3186,10 +3144,6 @@ msgstr ""
msgid "Notify me when available" msgid "Notify me when available"
msgstr "" msgstr ""
#: frontend/src/pages/BatchForm.vue:161
msgid "Number of seats available"
msgstr ""
#. Label of the sb_00 (Section Break) field in DocType 'Zoom Settings' #. Label of the sb_00 (Section Break) field in DocType 'Zoom Settings'
#: lms/lms/doctype/zoom_settings/zoom_settings.json #: lms/lms/doctype/zoom_settings/zoom_settings.json
msgid "OAuth Client ID" msgid "OAuth Client ID"
@@ -3222,7 +3176,7 @@ msgstr ""
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:473 frontend/src/utils/index.js:518 #: frontend/src/pages/CourseForm.vue:449 frontend/src/utils/index.js:509
msgid "Only image file is allowed." msgid "Only image file is allowed."
msgstr "" msgstr ""
@@ -3330,14 +3284,14 @@ msgid "Pages"
msgstr "" msgstr ""
#. Label of the paid_batch (Check) field in DocType 'LMS Batch' #. Label of the paid_batch (Check) field in DocType 'LMS Batch'
#: frontend/src/pages/BatchForm.vue:204 #: frontend/src/pages/BatchForm.vue:194
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/public/js/common_functions.js:373 #: lms/public/js/common_functions.js:373
msgid "Paid Batch" msgid "Paid Batch"
msgstr "" msgstr ""
#. Label of the paid_course (Check) field in DocType 'LMS Course' #. Label of the paid_course (Check) field in DocType 'LMS Course'
#: frontend/src/pages/CourseForm.vue:205 #: frontend/src/pages/CourseForm.vue:181
#: lms/lms/doctype/lms_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
msgid "Paid Course" msgid "Paid Course"
msgstr "" msgstr ""
@@ -3379,13 +3333,9 @@ msgstr ""
msgid "Password" msgid "Password"
msgstr "" msgstr ""
#: frontend/src/pages/CourseForm.vue:104
msgid "Paste the youtube link of a short video introducing the course"
msgstr ""
#. Label of the payment (Link) field in DocType 'Batch Student' #. Label of the payment (Link) field in DocType 'Batch Student'
#. Label of the payment (Link) field in DocType 'LMS Enrollment' #. Label of the payment (Link) field in DocType 'LMS Enrollment'
#: frontend/src/pages/BatchForm.vue:198 #: frontend/src/pages/BatchForm.vue:188
#: lms/lms/doctype/batch_student/batch_student.json #: lms/lms/doctype/batch_student/batch_student.json
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json #: lms/lms/doctype/lms_enrollment/lms_enrollment.json
msgid "Payment" msgid "Payment"
@@ -3477,7 +3427,7 @@ msgstr ""
msgid "Phone Number" msgid "Phone Number"
msgstr "" msgstr ""
#: frontend/src/components/CourseCardOverlay.vue:141 #: frontend/src/components/CourseCardOverlay.vue:143
msgid "Please Login" msgid "Please Login"
msgstr "" msgstr ""
@@ -3538,7 +3488,7 @@ msgstr ""
msgid "Please login to access this page." msgid "Please login to access this page."
msgstr "" msgstr ""
#: lms/lms/api.py:183 #: lms/lms/api.py:182
msgid "Please login to continue with payment." msgid "Please login to continue with payment."
msgstr "" msgstr ""
@@ -3628,7 +3578,7 @@ msgstr ""
msgid "Preview Image" msgid "Preview Image"
msgstr "" msgstr ""
#: frontend/src/pages/CourseForm.vue:102 #: frontend/src/pages/CourseForm.vue:86
msgid "Preview Video" msgid "Preview Video"
msgstr "" msgstr ""
@@ -3638,7 +3588,7 @@ msgstr ""
#. Label of the pricing_tab (Tab Break) field in DocType 'LMS Batch' #. Label of the pricing_tab (Tab Break) field in DocType 'LMS Batch'
#. Label of the pricing_tab (Tab Break) field in DocType 'LMS Course' #. Label of the pricing_tab (Tab Break) field in DocType 'LMS Course'
#: frontend/src/pages/CourseForm.vue:199 #: frontend/src/pages/CourseForm.vue:175
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/lms/doctype/lms_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
#: lms/public/js/common_functions.js:368 #: lms/public/js/common_functions.js:368
@@ -3656,7 +3606,7 @@ msgstr ""
msgid "Primary Subgroup" msgid "Primary Subgroup"
msgstr "" msgstr ""
#: lms/lms/utils.py:441 #: lms/lms/utils.py:422
msgid "Privacy Policy" msgid "Privacy Policy"
msgstr "" msgstr ""
@@ -3708,7 +3658,7 @@ msgstr ""
#. Label of the published (Check) field in DocType 'LMS Batch' #. Label of the published (Check) field in DocType 'LMS Batch'
#. Label of the published (Check) field in DocType 'LMS Course' #. Label of the published (Check) field in DocType 'LMS Course'
#: frontend/src/components/Modals/Event.vue:108 #: frontend/src/components/Modals/Event.vue:108
#: frontend/src/pages/BatchForm.vue:24 frontend/src/pages/CourseForm.vue:162 #: frontend/src/pages/BatchForm.vue:24 frontend/src/pages/CourseForm.vue:138
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/lms/doctype/lms_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
#: lms/public/js/common_functions.js:266 #: lms/public/js/common_functions.js:266
@@ -3721,7 +3671,7 @@ msgid "Published Courses"
msgstr "" msgstr ""
#. Label of the published_on (Date) field in DocType 'LMS Course' #. Label of the published_on (Date) field in DocType 'LMS Course'
#: frontend/src/pages/CourseForm.vue:166 #: frontend/src/pages/CourseForm.vue:142
#: lms/lms/doctype/lms_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
msgid "Published On" msgid "Published On"
msgstr "" msgstr ""
@@ -3842,13 +3792,11 @@ msgid "Quizzes"
msgstr "" msgstr ""
#. Label of the rating (Rating) field in DocType 'LMS Certificate Evaluation' #. Label of the rating (Rating) field in DocType 'LMS Certificate Evaluation'
#. Label of the rating (Data) field in DocType 'LMS Course'
#. Label of the rating (Rating) field in DocType 'LMS Course Review' #. Label of the rating (Rating) field in DocType 'LMS Course Review'
#: frontend/src/components/CourseCardOverlay.vue:108 #: frontend/src/components/CourseCardOverlay.vue:109
#: frontend/src/components/Modals/Event.vue:86 #: frontend/src/components/Modals/Event.vue:86
#: frontend/src/components/Modals/ReviewModal.vue:20 #: frontend/src/components/Modals/ReviewModal.vue:20
#: lms/lms/doctype/lms_certificate_evaluation/lms_certificate_evaluation.json #: lms/lms/doctype/lms_certificate_evaluation/lms_certificate_evaluation.json
#: lms/lms/doctype/lms_course/lms_course.json
#: lms/lms/doctype/lms_course_review/lms_course_review.json #: lms/lms/doctype/lms_course_review/lms_course_review.json
#: lms/templates/reviews.html:125 #: lms/templates/reviews.html:125
msgid "Rating" msgid "Rating"
@@ -3919,10 +3867,6 @@ msgstr ""
msgid "Related Courses" msgid "Related Courses"
msgstr "" msgstr ""
#: frontend/src/pages/BatchForm.vue:69 frontend/src/pages/CourseForm.vue:91
msgid "Remove"
msgstr ""
#: frontend/src/components/Modals/AnnouncementModal.vue:26 #: frontend/src/components/Modals/AnnouncementModal.vue:26
msgid "Reply To" msgid "Reply To"
msgstr "" msgstr ""
@@ -4078,7 +4022,7 @@ msgid "Search for an icon"
msgstr "" msgstr ""
#. Label of the seat_count (Int) field in DocType 'LMS Batch' #. Label of the seat_count (Int) field in DocType 'LMS Batch'
#: frontend/src/pages/BatchForm.vue:158 #: frontend/src/pages/BatchForm.vue:149
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/public/js/common_functions.js:327 #: lms/public/js/common_functions.js:327
msgid "Seat Count" msgid "Seat Count"
@@ -4122,7 +4066,7 @@ msgid "Set your Password"
msgstr "" msgstr ""
#: frontend/src/components/Modals/Settings.vue:7 #: frontend/src/components/Modals/Settings.vue:7
#: frontend/src/pages/BatchForm.vue:152 frontend/src/pages/CourseForm.vue:152 #: frontend/src/pages/BatchForm.vue:143 frontend/src/pages/CourseForm.vue:128
#: frontend/src/pages/ProfileRoles.vue:4 frontend/src/pages/QuizForm.vue:78 #: frontend/src/pages/ProfileRoles.vue:4 frontend/src/pages/QuizForm.vue:78
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
@@ -4132,15 +4076,11 @@ msgid "Share on"
msgstr "" msgstr ""
#. Label of the short_introduction (Small Text) field in DocType 'LMS Course' #. Label of the short_introduction (Small Text) field in DocType 'LMS Course'
#: frontend/src/pages/CourseForm.vue:30 #: frontend/src/pages/CourseForm.vue:29
#: lms/lms/doctype/lms_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
msgid "Short Introduction" msgid "Short Introduction"
msgstr "" msgstr ""
#: frontend/src/pages/BatchForm.vue:93
msgid "Short description of the batch"
msgstr ""
#. Label of the show_answer (Check) field in DocType 'LMS Assignment' #. Label of the show_answer (Check) field in DocType 'LMS Assignment'
#: lms/lms/doctype/lms_assignment/lms_assignment.json #: lms/lms/doctype/lms_assignment/lms_assignment.json
msgid "Show Answer" msgid "Show Answer"
@@ -4301,7 +4241,7 @@ msgstr ""
#. Label of the start_date (Date) field in DocType 'Education Detail' #. Label of the start_date (Date) field in DocType 'Education Detail'
#. Label of the start_date (Date) field in DocType 'LMS Batch' #. Label of the start_date (Date) field in DocType 'LMS Batch'
#. Label of the start_date (Date) field in DocType 'LMS Batch Old' #. Label of the start_date (Date) field in DocType 'LMS Batch Old'
#: frontend/src/pages/BatchForm.vue:116 #: frontend/src/pages/BatchForm.vue:108
#: lms/lms/doctype/education_detail/education_detail.json #: lms/lms/doctype/education_detail/education_detail.json
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/lms/doctype/lms_batch_old/lms_batch_old.json #: lms/lms/doctype/lms_batch_old/lms_batch_old.json
@@ -4322,7 +4262,7 @@ msgstr ""
#. Label of the start_time (Time) field in DocType 'LMS Certificate Evaluation' #. Label of the start_time (Time) field in DocType 'LMS Certificate Evaluation'
#. Label of the start_time (Time) field in DocType 'LMS Certificate Request' #. Label of the start_time (Time) field in DocType 'LMS Certificate Request'
#. Label of the start_time (Time) field in DocType 'Scheduled Flow' #. Label of the start_time (Time) field in DocType 'Scheduled Flow'
#: frontend/src/pages/BatchForm.vue:130 #: frontend/src/pages/BatchForm.vue:122
#: frontend/src/pages/ProfileEvaluator.vue:15 #: frontend/src/pages/ProfileEvaluator.vue:15
#: lms/lms/doctype/evaluator_schedule/evaluator_schedule.json #: lms/lms/doctype/evaluator_schedule/evaluator_schedule.json
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
@@ -4361,9 +4301,7 @@ msgstr ""
msgid "State" msgid "State"
msgstr "" msgstr ""
#. Label of the tab_4_tab (Tab Break) field in DocType 'LMS Course'
#. Label of the statistics (Check) field in DocType 'LMS Settings' #. Label of the statistics (Check) field in DocType 'LMS Settings'
#: lms/lms/doctype/lms_course/lms_course.json
#: lms/lms/doctype/lms_settings/lms_settings.json lms/www/lms.py:133 #: lms/lms/doctype/lms_settings/lms_settings.json lms/www/lms.py:133
msgid "Statistics" msgid "Statistics"
msgstr "" msgstr ""
@@ -4493,7 +4431,7 @@ msgstr ""
#: frontend/src/components/BatchCourses.vue:150 #: frontend/src/components/BatchCourses.vue:150
#: frontend/src/components/BatchOverlay.vue:135 #: frontend/src/components/BatchOverlay.vue:135
#: frontend/src/components/BatchStudents.vue:157 #: frontend/src/components/BatchStudents.vue:157
#: frontend/src/components/CourseCardOverlay.vue:161 #: frontend/src/components/CourseCardOverlay.vue:163
#: frontend/src/components/Modals/AssessmentModal.vue:73 #: frontend/src/components/Modals/AssessmentModal.vue:73
#: 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
@@ -4567,7 +4505,7 @@ msgid "System Manager"
msgstr "" msgstr ""
#. Label of the tags (Data) field in DocType 'LMS Course' #. Label of the tags (Data) field in DocType 'LMS Course'
#: frontend/src/pages/CourseForm.vue:112 #: frontend/src/pages/CourseForm.vue:91
#: lms/lms/doctype/lms_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
msgid "Tags" msgid "Tags"
msgstr "" msgstr ""
@@ -4595,7 +4533,7 @@ msgstr ""
msgid "Temporarily Disabled" msgid "Temporarily Disabled"
msgstr "" msgstr ""
#: lms/lms/utils.py:440 #: lms/lms/utils.py:421
msgid "Terms of Use" msgid "Terms of Use"
msgstr "" msgstr ""
@@ -4647,18 +4585,10 @@ msgstr ""
msgid "The status of your application has changed." msgid "The status of your application has changed."
msgstr "" msgstr ""
#: frontend/src/pages/Batches.vue:129
msgid "There are no batches available at the moment. Keep an eye out, fresh learning experiences are on the way soon!"
msgstr ""
#: frontend/src/components/CreateOutline.vue:12 #: frontend/src/components/CreateOutline.vue:12
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
msgid "There are no courses 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:140 #: lms/lms/doctype/lms_batch/lms_batch.py:140
msgid "There are no seats available in this batch." msgid "There are no seats available in this batch."
msgstr "" msgstr ""
@@ -4690,7 +4620,7 @@ msgstr ""
msgid "This course has:" msgid "This course has:"
msgstr "" msgstr ""
#: lms/lms/utils.py:1572 #: lms/lms/utils.py:1563
msgid "This course is free." msgid "This course is free."
msgstr "" msgstr ""
@@ -4759,7 +4689,7 @@ msgstr ""
#. Label of the timezone (Data) field in DocType 'LMS Certificate Request' #. Label of the timezone (Data) field in DocType 'LMS Certificate Request'
#. Label of the timezone (Data) field in DocType 'LMS Live Class' #. Label of the timezone (Data) field in DocType 'LMS Live Class'
#: frontend/src/components/Modals/LiveClassModal.vue:44 #: frontend/src/components/Modals/LiveClassModal.vue:44
#: frontend/src/pages/BatchForm.vue:142 #: frontend/src/pages/BatchForm.vue:134
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.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_live_class/lms_live_class.json #: lms/lms/doctype/lms_live_class/lms_live_class.json
@@ -4825,7 +4755,7 @@ msgstr ""
msgid "To Date is mandatory in Work Experience." msgid "To Date is mandatory in Work Experience."
msgstr "" msgstr ""
#: lms/lms/utils.py:1583 #: lms/lms/utils.py:1574
msgid "To join this batch, please contact the Administrator." msgid "To join this batch, please contact the Administrator."
msgstr "" msgstr ""
@@ -4942,7 +4872,7 @@ msgstr ""
#. Option for the 'Status' (Select) field in DocType 'Cohort' #. Option for the 'Status' (Select) field in DocType 'Cohort'
#. Label of the upcoming (Check) field in DocType 'LMS Course' #. Label of the upcoming (Check) field in DocType 'LMS Course'
#: frontend/src/pages/CourseForm.vue:175 lms/lms/doctype/cohort/cohort.json #: frontend/src/pages/CourseForm.vue:151 lms/lms/doctype/cohort/cohort.json
#: lms/lms/doctype/lms_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
msgid "Upcoming" msgid "Upcoming"
msgstr "" msgstr ""
@@ -4966,10 +4896,6 @@ msgstr ""
msgid "Update Password" msgid "Update Password"
msgstr "" msgstr ""
#: frontend/src/pages/BatchForm.vue:51 frontend/src/pages/CourseForm.vue:72
msgid "Upload"
msgstr ""
#: frontend/src/pages/AssignmentSubmission.vue:69 #: frontend/src/pages/AssignmentSubmission.vue:69
msgid "Upload File" msgid "Upload File"
msgstr "" msgstr ""
@@ -5092,10 +5018,6 @@ msgstr ""
msgid "Welcome to {0}!" msgid "Welcome to {0}!"
msgstr "" msgstr ""
#: frontend/src/components/LessonHelp.vue:63
msgid "What does include in preview mean?"
msgstr ""
#: lms/templates/courses_under_review.html:15 #: lms/templates/courses_under_review.html:15
msgid "When a course gets submitted for review, it will be listed here." msgid "When a course gets submitted for review, it will be listed here."
msgstr "" msgstr ""
@@ -5149,11 +5071,11 @@ msgstr ""
msgid "You already have an evaluation on {0} at {1} for the course {2}." msgid "You already have an evaluation on {0} at {1} for the course {2}."
msgstr "" msgstr ""
#: lms/lms/api.py:207 #: lms/lms/api.py:206
msgid "You are already enrolled for this batch." msgid "You are already enrolled for this batch."
msgstr "" msgstr ""
#: lms/lms/api.py:199 #: lms/lms/api.py:198
msgid "You are already enrolled for this course." msgid "You are already enrolled for this course."
msgstr "" msgstr ""
@@ -5165,10 +5087,6 @@ msgstr ""
msgid "You are not a mentor of the course {0}" msgid "You are not a mentor of the course {0}"
msgstr "" msgstr ""
#: frontend/src/pages/Courses.vue:134
msgid "You can add chapters and lessons to it."
msgstr ""
#: lms/templates/emails/lms_course_interest.html:13 #: lms/templates/emails/lms_course_interest.html:13
#: lms/templates/emails/lms_invite_request_approved.html:11 #: lms/templates/emails/lms_invite_request_approved.html:11
msgid "You can also copy-paste following link in your browser" msgid "You can also copy-paste following link in your browser"
@@ -5186,10 +5104,6 @@ msgstr ""
msgid "You can find their resume attached to this email." msgid "You can find their resume attached to this email."
msgstr "" msgstr ""
#: frontend/src/pages/Batches.vue:113
msgid "You can link courses and assessments to it."
msgstr ""
#: lms/lms/doctype/lms_certificate_request/lms_certificate_request.py:115 #: lms/lms/doctype/lms_certificate_request/lms_certificate_request.py:115
msgid "You cannot schedule evaluations after {0}." msgid "You cannot schedule evaluations after {0}."
msgstr "" msgstr ""
@@ -5231,7 +5145,7 @@ msgstr ""
msgid "You have been enrolled in this batch" msgid "You have been enrolled in this batch"
msgstr "" msgstr ""
#: frontend/src/components/CourseCardOverlay.vue:162 #: frontend/src/components/CourseCardOverlay.vue:164
msgid "You have been enrolled in this course" msgid "You have been enrolled in this course"
msgstr "" msgstr ""
@@ -5243,7 +5157,7 @@ msgstr ""
msgid "You haven't enrolled for any courses" msgid "You haven't enrolled for any courses"
msgstr "" msgstr ""
#: frontend/src/components/CourseCardOverlay.vue:142 #: frontend/src/components/CourseCardOverlay.vue:144
msgid "You need to login first to enroll for this course" msgid "You need to login first to enroll for this course"
msgstr "" msgstr ""
@@ -5361,7 +5275,7 @@ msgstr ""
msgid "you can" msgid "you can"
msgstr "" msgstr ""
#: lms/lms/api.py:732 lms/lms/api.py:740 #: lms/lms/api.py:731 lms/lms/api.py:739
msgid "{0} Settings not found" msgid "{0} Settings not found"
msgstr "" msgstr ""
@@ -5397,7 +5311,7 @@ msgstr ""
msgid "{0} is your evaluator" msgid "{0} is your evaluator"
msgstr "" msgstr ""
#: lms/lms/utils.py:709 #: lms/lms/utils.py:690
msgid "{0} mentioned you in a comment" msgid "{0} mentioned you in a comment"
msgstr "" msgstr ""
@@ -5405,11 +5319,11 @@ msgstr ""
msgid "{0} mentioned you in a comment in your batch." msgid "{0} mentioned you in a comment in your batch."
msgstr "" msgstr ""
#: lms/lms/utils.py:662 lms/lms/utils.py:668 #: lms/lms/utils.py:643 lms/lms/utils.py:649
msgid "{0} mentioned you in a comment in {1}" msgid "{0} mentioned you in a comment in {1}"
msgstr "" msgstr ""
#: lms/lms/utils.py:480 #: lms/lms/utils.py:461
msgid "{0}k" msgid "{0}k"
msgstr "" msgstr ""

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -90,5 +90,4 @@ lms.patches.v1_0.set_published_on
lms.patches.v2_0.fix_progress_percentage lms.patches.v2_0.fix_progress_percentage
lms.patches.v2_0.add_discussion_topic_titles lms.patches.v2_0.add_discussion_topic_titles
lms.patches.v2_0.sidebar_settings 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

View File

@@ -1,6 +0,0 @@
import frappe
from lms.lms.api import update_course_statistics
def execute():
update_course_statistics()