fix: course count on batch dashboard

This commit is contained in:
Jannat Patel
2025-05-26 12:25:16 +05:30
36 changed files with 1234 additions and 585 deletions

View File

@@ -1,12 +1,15 @@
describe("Course Creation", () => { describe("Course Creation", () => {
it("creates a new course", () => { it("creates a new course", () => {
cy.login(); cy.login();
cy.wait(1000); cy.wait(500);
cy.visit("/lms/courses"); cy.visit("/lms/courses");
// Close onboarding modal
cy.closeOnboardingModal();
// Create a course // Create a course
cy.get("button").contains("New").click(); cy.get("button").contains("New").click();
cy.wait(1000); cy.wait(500);
cy.url().should("include", "/courses/new/edit"); cy.url().should("include", "/courses/new/edit");
cy.get("label").contains("Title").type("Test Course"); cy.get("label").contains("Title").type("Test Course");
@@ -96,7 +99,8 @@ describe("Course Creation", () => {
// View Course // View Course
cy.wait(1000); cy.wait(1000);
cy.visit("/lms"); cy.visit("/lms");
cy.wait(500); cy.closeOnboardingModal();
cy.url().should("include", "/lms/courses"); cy.url().should("include", "/lms/courses");
cy.get(".grid a:first").within(() => { cy.get(".grid a:first").within(() => {
cy.get("div").contains("Test Course"); cy.get("div").contains("Test Course");

View File

@@ -25,6 +25,7 @@
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
import "cypress-file-upload"; import "cypress-file-upload";
import "cypress-real-events";
Cypress.Commands.add("login", (email, password) => { Cypress.Commands.add("login", (email, password) => {
if (!email) { if (!email) {
@@ -68,3 +69,11 @@ Cypress.Commands.add("paste", { prevSubject: true }, (subject, text) => {
element.dispatchEvent(event); element.dispatchEvent(event);
}); });
}); });
Cypress.Commands.add("closeOnboardingModal", () => {
cy.wait(500);
cy.get('[class*="z-50"]')
.find('button:has(svg[class*="feather-x"])')
.realClick();
cy.wait(1000);
});

View File

@@ -47,11 +47,14 @@ declare module 'vue' {
Discussions: typeof import('./src/components/Discussions.vue')['default'] Discussions: typeof import('./src/components/Discussions.vue')['default']
EditCoverImage: typeof import('./src/components/Modals/EditCoverImage.vue')['default'] EditCoverImage: typeof import('./src/components/Modals/EditCoverImage.vue')['default']
EditProfile: typeof import('./src/components/Modals/EditProfile.vue')['default'] EditProfile: typeof import('./src/components/Modals/EditProfile.vue')['default']
EmailTemplateModal: typeof import('./src/components/Modals/EmailTemplateModal.vue')['default']
EmailTemplates: typeof import('./src/components/EmailTemplates.vue')['default']
EmptyState: typeof import('./src/components/EmptyState.vue')['default'] EmptyState: typeof import('./src/components/EmptyState.vue')['default']
EvaluationModal: typeof import('./src/components/Modals/EvaluationModal.vue')['default'] EvaluationModal: typeof import('./src/components/Modals/EvaluationModal.vue')['default']
Evaluators: typeof import('./src/components/Evaluators.vue')['default'] Evaluators: typeof import('./src/components/Evaluators.vue')['default']
Event: typeof import('./src/components/Modals/Event.vue')['default'] Event: typeof import('./src/components/Modals/Event.vue')['default']
ExplanationVideos: typeof import('./src/components/Modals/ExplanationVideos.vue')['default'] ExplanationVideos: typeof import('./src/components/Modals/ExplanationVideos.vue')['default']
FeedbackModal: typeof import('./src/components/Modals/FeedbackModal.vue')['default']
FrappeCloudIcon: typeof import('./src/components/Icons/FrappeCloudIcon.vue')['default'] FrappeCloudIcon: typeof import('./src/components/Icons/FrappeCloudIcon.vue')['default']
IconPicker: typeof import('./src/components/Controls/IconPicker.vue')['default'] IconPicker: typeof import('./src/components/Controls/IconPicker.vue')['default']
IndicatorIcon: typeof import('./src/components/Icons/IndicatorIcon.vue')['default'] IndicatorIcon: typeof import('./src/components/Icons/IndicatorIcon.vue')['default']

View File

@@ -39,9 +39,9 @@ const Layout = computed(() => {
} }
if (screenSize.width < 640) { if (screenSize.width < 640) {
return MobileLayout return MobileLayout
} else {
return DesktopLayout
} }
return DesktopLayout
}) })
onMounted(async () => { onMounted(async () => {

View File

@@ -181,7 +181,6 @@
import UserDropdown from '@/components/UserDropdown.vue' import UserDropdown from '@/components/UserDropdown.vue'
import CollapseSidebar from '@/components/Icons/CollapseSidebar.vue' import CollapseSidebar from '@/components/Icons/CollapseSidebar.vue'
import SidebarLink from '@/components/SidebarLink.vue' import SidebarLink from '@/components/SidebarLink.vue'
import { useStorage } from '@vueuse/core'
import { ref, onMounted, inject, watch, reactive, markRaw, h } from 'vue' import { ref, onMounted, inject, watch, reactive, markRaw, h } from 'vue'
import { getSidebarLinks } from '../utils' import { getSidebarLinks } from '../utils'
import { usersStore } from '@/stores/user' import { usersStore } from '@/stores/user'
@@ -244,6 +243,7 @@ const iconProps = {
onMounted(() => { onMounted(() => {
addNotifications() addNotifications()
setSidebarLinks() setSidebarLinks()
setUpOnboarding()
socket.on('publish_lms_notifications', (data) => { socket.on('publish_lms_notifications', (data) => {
unreadNotifications.reload() unreadNotifications.reload()
}) })
@@ -388,10 +388,6 @@ const deletePage = (link) => {
) )
} }
const getSidebarFromStorage = () => {
return useStorage('sidebar_is_collapsed', false)
}
const toggleSidebar = () => { const toggleSidebar = () => {
sidebarStore.isSidebarCollapsed = !sidebarStore.isSidebarCollapsed sidebarStore.isSidebarCollapsed = !sidebarStore.isSidebarCollapsed
localStorage.setItem( localStorage.setItem(
@@ -438,6 +434,7 @@ const steps = reactive([
title: __('Add your first chapter'), title: __('Add your first chapter'),
icon: markRaw(h(FolderTree, iconProps)), icon: markRaw(h(FolderTree, iconProps)),
completed: false, completed: false,
dependsOn: 'create_first_course',
onClick: async () => { onClick: async () => {
minimize.value = true minimize.value = true
let course = await getFirstCourse() let course = await getFirstCourse()
@@ -453,6 +450,7 @@ const steps = reactive([
title: __('Add your first lesson'), title: __('Add your first lesson'),
icon: markRaw(h(FileText, iconProps)), icon: markRaw(h(FileText, iconProps)),
completed: false, completed: false,
dependsOn: 'create_first_chapter',
onClick: async () => { onClick: async () => {
minimize.value = true minimize.value = true
let course = await getFirstCourse() let course = await getFirstCourse()
@@ -471,6 +469,7 @@ const steps = reactive([
title: __('Create your first quiz'), title: __('Create your first quiz'),
icon: markRaw(h(CircleHelp, iconProps)), icon: markRaw(h(CircleHelp, iconProps)),
completed: false, completed: false,
dependsOn: 'create_first_course',
onClick: () => { onClick: () => {
minimize.value = true minimize.value = true
router.push({ name: 'Quizzes' }) router.push({ name: 'Quizzes' })
@@ -502,6 +501,7 @@ const steps = reactive([
title: __('Add students to your batch'), title: __('Add students to your batch'),
icon: markRaw(h(UserPlus, iconProps)), icon: markRaw(h(UserPlus, iconProps)),
completed: false, completed: false,
dependsOn: 'create_first_batch',
onClick: async () => { onClick: async () => {
minimize.value = true minimize.value = true
let batch = await getFirstBatch() let batch = await getFirstBatch()
@@ -522,6 +522,7 @@ const steps = reactive([
title: __('Add courses to your batch'), title: __('Add courses to your batch'),
icon: markRaw(h(BookText, iconProps)), icon: markRaw(h(BookText, iconProps)),
completed: false, completed: false,
dependsOn: 'create_first_batch',
onClick: async () => { onClick: async () => {
minimize.value = true minimize.value = true
let batch = await getFirstBatch() let batch = await getFirstBatch()

View File

@@ -1,44 +1,49 @@
<template> <template>
<div v-if="user.data?.is_student"> <div v-if="user.data?.is_student">
<div <div>
v-if="feedbackList.data?.length" <div class="leading-5 mb-4">
class="bg-surface-blue-2 text-blue-700 p-2 rounded-md mb-5" <div v-if="readOnly">
> {{ __('Thank you for providing your feedback.') }}
{{ __('Thank you for providing your feedback!') }} <span
</div> @click="showFeedbackForm = !showFeedbackForm"
<div v-else class="flex justify-between items-center mb-5"> class="underline cursor-pointer"
<div class="text-lg font-semibold"> >{{ __('Click here') }}</span
{{ __('Help Us Improve') }} >
{{ __('to view your feedback.') }}
</div>
<div v-else>
{{ __('Help us improve by providing your feedback.') }}
</div>
</div> </div>
<Button @click="submitFeedback()"> <div class="space-y-4" :class="showFeedbackForm ? 'block' : 'hidden'">
{{ __('Submit') }} <div class="space-y-4">
</Button> <Rating
</div> v-for="key in ratingKeys"
<div class="space-y-8"> v-model="feedback[key]"
<div class="flex items-center justify-between"> :label="__(convertToTitleCase(key))"
<Rating :readonly="readOnly"
v-for="key in ratingKeys" />
v-model="feedback[key]" </div>
:label="__(convertToTitleCase(key))" <FormControl
v-model="feedback.feedback"
type="textarea"
:label="__('Feedback')"
:rows="9"
:readonly="readOnly" :readonly="readOnly"
/> />
<Button v-if="!readOnly" @click="submitFeedback">
{{ __('Submit Feedback') }}
</Button>
</div> </div>
<FormControl
v-model="feedback.feedback"
type="textarea"
:label="__('Feedback')"
:rows="7"
:readonly="readOnly"
/>
</div> </div>
</div> </div>
<div v-else-if="feedbackList.data?.length"> <div v-else-if="feedbackList.data?.length">
<div class="text-lg font-semibold mb-5"> <div class="leading-5 text-sm mb-2 mt-5">
{{ __('Average of Feedback Received') }} {{ __('Average Feedback Received') }}
</div> </div>
<div class="flex items-center justify-between mb-10"> <div class="space-y-4">
<Rating <Rating
v-for="key in ratingKeys" v-for="key in ratingKeys"
v-model="average[key]" v-model="average[key]"
@@ -47,81 +52,32 @@
/> />
</div> </div>
<div class="text-lg font-semibold mb-5"> <Button variant="outline" class="mt-5" @click="showAllFeedback = true">
{{ __('All Feedback') }} {{ __('View all feedback') }}
</div> </Button>
<ListView
:columns="feedbackColumns"
:rows="feedbackList.data"
row-key="name"
:options="{
showTooltip: false,
rowHeight: 'h-16',
selectable: false,
}"
>
<ListHeader
class="mb-2 grid items-center space-x-4 rounded bg-surface-gray-2 p-2"
></ListHeader>
<ListRows>
<ListRow
:row="row"
v-for="row in feedbackList.data"
class="group cursor-pointer feedback-list"
>
<template #default="{ column, item }">
<ListRowItem
:item="row[column.key]"
:align="column.align"
class="text-sm"
>
<template #prefix>
<div v-if="column.key == 'member_name'">
<Avatar
class="flex"
:image="row['member_image']"
:label="item"
size="sm"
/>
</div>
</template>
<div v-if="ratingKeys.includes(column.key)">
<Rating v-model="row[column.key]" :readonly="true" />
</div>
<div v-else class="leading-5">
{{ row[column.key] }}
</div>
</ListRowItem>
</template>
</ListRow>
</ListRows>
</ListView>
</div> </div>
<div v-else class="text-sm italic text-center text-ink-gray-7 mt-5"> <div v-else class="text-ink-gray-7 mt-5 leading-5">
{{ __('No feedback received yet.') }} {{ __('No feedback received yet.') }}
</div> </div>
<FeedbackModal
v-if="feedbackList.data?.length"
v-model="showAllFeedback"
:feedbackList="feedbackList.data"
/>
</template> </template>
<script setup> <script setup>
import { computed, inject, onMounted, reactive, ref, watch } from 'vue' import { inject, onMounted, reactive, ref, watch } from 'vue'
import { convertToTitleCase } from '@/utils' import { convertToTitleCase } from '@/utils'
import { import { Button, createListResource, FormControl, Rating } from 'frappe-ui'
Avatar, import FeedbackModal from '@/components/Modals/FeedbackModal.vue'
Button,
createListResource,
FormControl,
ListView,
ListHeader,
ListRows,
ListRow,
ListRowItem,
Rating,
} from 'frappe-ui'
const user = inject('$user') const user = inject('$user')
const ratingKeys = ['content', 'instructors', 'value'] const ratingKeys = ['content', 'instructors', 'value']
const readOnly = ref(false) const readOnly = ref(false)
const average = reactive({}) const average = reactive({})
const feedback = reactive({}) const feedback = reactive({})
const showFeedbackForm = ref(true)
const showAllFeedback = ref(false)
const props = defineProps({ const props = defineProps({
batch: { batch: {
@@ -167,6 +123,7 @@ watch(
if (feedbackList.data.length) { if (feedbackList.data.length) {
let data = feedbackList.data let data = feedbackList.data
readOnly.value = true readOnly.value = true
showFeedbackForm.value = false
ratingKeys.forEach((key) => { ratingKeys.forEach((key) => {
average[key] = 0 average[key] = 0
@@ -201,40 +158,11 @@ const submitFeedback = () => {
{ {
onSuccess: () => { onSuccess: () => {
feedbackList.reload() feedbackList.reload()
showFeedbackForm.value = false
}, },
} }
) )
} }
const feedbackColumns = computed(() => {
return [
{
label: 'Member',
key: 'member_name',
width: '10rem',
},
{
label: 'Feedback',
key: 'feedback',
width: '15rem',
},
{
label: 'Content',
key: 'content',
width: '9rem',
},
{
label: 'Instructors',
key: 'instructors',
width: '9rem',
},
{
label: 'Value',
key: 'value',
width: '9rem',
},
]
})
</script> </script>
<style> <style>
.feedback-list > button > div { .feedback-list > button > div {

View File

@@ -18,11 +18,11 @@
</div> </div>
<div class="overflow-y-auto"> <div class="overflow-y-auto">
<SettingFields :fields="fields" :data="data.data" /> <SettingFields :fields="fields" :data="data.data" />
<div class="flex flex-row-reverse mt-auto"> </div>
<Button variant="solid" :loading="saveSettings.loading" @click="update"> <div class="flex flex-row-reverse mt-auto">
{{ __('Update') }} <Button variant="solid" :loading="saveSettings.loading" @click="update">
</Button> {{ __('Update') }}
</div> </Button>
</div> </div>
</div> </div>
</template> </template>

View File

@@ -1,16 +1,32 @@
<template> <template>
<div class="flex flex-col min-h-0"> <div class="flex flex-col min-h-0 text-base">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between mb-5">
<div class="text-xl font-semibold mb-5 text-ink-gray-9"> <div class="flex flex-col space-y-2">
{{ label }} <div class="text-xl font-semibold text-ink-gray-9">
{{ label }}
</div>
<div class="text-xs text-ink-gray-5">
{{ __(description) }}
</div>
</div>
<div class="flex items-center space-x-5">
<div
class="flex items-center space-x-1 text-ink-amber-3 border border-outline-amber-1 bg-surface-amber-1 rounded-lg px-2 py-1"
v-if="saving"
>
<LoadingIndicator class="size-2" />
<span class="text-xs">
{{ __('saving...') }}
</span>
</div>
<Button @click="() => showCategoryForm()">
<template #prefix>
<Plus v-if="!showForm" class="h-3 w-3 stroke-1.5" />
<X v-else class="h-3 w-3 stroke-1.5" />
</template>
{{ showForm ? __('Close') : __('New') }}
</Button>
</div> </div>
<Button @click="() => showCategoryForm()">
<template #prefix>
<Plus v-if="!showForm" class="h-3 w-3 stroke-1.5" />
<X v-else class="h-3 w-3 stroke-1.5" />
</template>
{{ showForm ? __('Close') : __('New') }}
</Button>
</div> </div>
<div <div
@@ -29,13 +45,39 @@
</div> </div>
<div class="overflow-y-scroll"> <div class="overflow-y-scroll">
<div class="text-base space-y-2"> <div class="divide-y space-y-2">
<FormControl <div
:value="cat.category" v-for="(cat, index) in categories.data"
type="text" :key="cat.name"
v-for="cat in categories.data" class="pt-2"
@change.stop="(e) => update(cat.name, e.target.value)" >
/> <div
v-if="editing?.name !== cat.name"
class="flex items-center justify-between group text-sm"
>
<div @dblclick="allowEdit(cat, index)">
{{ cat.category }}
</div>
<Button
variant="ghost"
theme="red"
class="invisible group-hover:visible"
@click="deleteCategory(cat.name)"
>
<template #icon>
<Trash2 class="size-4 stroke-1.5 text-ink-red-4" />
</template>
</Button>
</div>
<FormControl
v-else
:ref="(el) => (editInputRef[index] = el)"
v-model="editedValue"
type="text"
class="w-full"
@keyup.enter="saveChanges(cat.name, editedValue)"
/>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -44,16 +86,22 @@
import { import {
Button, Button,
FormControl, FormControl,
LoadingIndicator,
createListResource, createListResource,
createResource, createResource,
debounce, toast,
} from 'frappe-ui' } from 'frappe-ui'
import { Plus, X } from 'lucide-vue-next' import { Plus, Trash2, X } from 'lucide-vue-next'
import { ref } from 'vue' import { ref } from 'vue'
import { cleanError } from '@/utils'
const showForm = ref(false) const showForm = ref(false)
const category = ref(null) const category = ref(null)
const categoryInput = ref(null) const categoryInput = ref(null)
const saving = ref(false)
const editing = ref(null)
const editedValue = ref('')
const editInputRef = ref([])
const props = defineProps({ const props = defineProps({
label: { label: {
@@ -72,25 +120,20 @@ const categories = createListResource({
auto: true, auto: true,
}) })
const newCategory = createResource({
url: 'frappe.client.insert',
makeParams(values) {
return {
doc: {
doctype: 'LMS Category',
category: category.value,
},
}
},
})
const addCategory = () => { const addCategory = () => {
newCategory.submit( categories.insert.submit(
{}, {
category: category.value,
},
{ {
onSuccess(data) { onSuccess(data) {
categories.reload() categories.reload()
category.value = null category.value = null
showForm.value = false
toast.success(__('Category added successfully'))
},
onError(err) {
toast.error(__(cleanError(err.messages[0]) || 'Unable to add category'))
}, },
} }
) )
@@ -115,6 +158,7 @@ const updateCategory = createResource({
}) })
const update = (name, value) => { const update = (name, value) => {
saving.value = true
updateCategory.submit( updateCategory.submit(
{ {
name: name, name: name,
@@ -122,9 +166,51 @@ const update = (name, value) => {
}, },
{ {
onSuccess() { onSuccess() {
saving.value = false
categories.reload() categories.reload()
editing.value = null
editedValue.value = ''
toast.success(__('Category updated successfully'))
},
onError(err) {
saving.value = false
editing.value = null
editedValue.value = ''
toast.error(
__(cleanError(err.messages[0]) || 'Unable to update category')
)
}, },
} }
) )
} }
const deleteCategory = (name) => {
saving.value = true
categories.delete.submit(name, {
onSuccess() {
saving.value = false
categories.reload()
toast.success(__('Category deleted successfully'))
},
onError(err) {
saving.value = false
toast.error(
__(cleanError(err.messages[0]) || 'Unable to delete category')
)
},
})
}
const saveChanges = (name, value) => {
saving.value = true
update(name, value)
}
const allowEdit = (cat, index) => {
editing.value = cat
editedValue.value = cat.category
setTimeout(() => {
editInputRef.value[index].$el.querySelector('input').focus()
}, 0)
}
</script> </script>

View File

@@ -116,7 +116,7 @@
v-if="parseInt(course.data.rating) > 0" v-if="parseInt(course.data.rating) > 0"
class="flex items-center text-ink-gray-9" class="flex items-center text-ink-gray-9"
> >
<Star class="h-4 w-4 stroke-1.5 fill-orange-500 text-gray-50" /> <Star class="size-4 stroke-1.5 fill-yellow-500 text-transparent" />
<span class="ml-2"> <span class="ml-2">
{{ course.data.rating }} {{ __('Rating') }} {{ course.data.rating }} {{ __('Rating') }}
</span> </span>

View File

@@ -35,14 +35,14 @@
<span class="text-ink-gray-7"> <span class="text-ink-gray-7">
{{ review.creation }} {{ review.creation }}
</span> </span>
<div class="flex mt-2"> <div class="flex mt-2 space-x-1">
<Star <Star
v-for="index in 5" v-for="index in 5"
class="h-5 w-5 text-ink-gray-1 rounded-sm mr-2" class="size-4 text-transparent rounded-sm"
:class=" :class="
index <= Math.ceil(review.rating) index <= Math.ceil(review.rating)
? 'fill-orange-500' ? 'fill-yellow-500'
: 'fill-gray-600' : 'fill-gray-300'
" "
/> />
</div> </div>

View File

@@ -0,0 +1,160 @@
<template>
<div class="flex flex-col min-h-0 text-base">
<div class="flex items-center justify-between mb-5">
<div class="flex flex-col space-y-2">
<div class="text-xl font-semibold text-ink-gray-9">
{{ label }}
</div>
<div class="text-xs text-ink-gray-5">
{{ __(description) }}
</div>
</div>
<div class="flex items-center space-x-5">
<Button @click="openTemplateForm('new')">
<template #prefix>
<Plus class="h-3 w-3 stroke-1.5" />
</template>
{{ __('New') }}
</Button>
</div>
</div>
<div v-if="emailTemplates.data?.length" class="overflow-y-scroll">
<ListView
:columns="columns"
:rows="emailTemplates.data"
row-key="name"
:options="{
showTooltip: false,
onRowClick: (row) => {
openTemplateForm(row.name)
},
}"
>
<ListHeader
class="mb-2 grid items-center space-x-4 rounded bg-surface-gray-2 p-2"
>
<ListHeaderItem :item="item" v-for="item in columns">
<template #prefix="{ item }">
<component
v-if="item.icon"
:is="item.icon"
class="h-4 w-4 stroke-1.5 ml-4"
/>
</template>
</ListHeaderItem>
</ListHeader>
<ListRows>
<ListRow :row="row" v-for="row in emailTemplates.data">
<template #default="{ column, item }">
<ListRowItem :item="row[column.key]" :align="column.align">
<div class="leading-5 text-sm">
{{ row[column.key] }}
</div>
</ListRowItem>
</template>
</ListRow>
</ListRows>
<ListSelectBanner>
<template #actions="{ unselectAll, selections }">
<div class="flex gap-2">
<Button
variant="ghost"
@click="removeTemplate(selections, unselectAll)"
>
<Trash2 class="h-4 w-4 stroke-1.5" />
</Button>
</div>
</template>
</ListSelectBanner>
</ListView>
</div>
</div>
<EmailTemplateModal
v-model="showForm"
v-model:emailTemplates="emailTemplates"
:templateID="selectedTemplate"
/>
</template>
<script setup lang="ts">
import {
Button,
call,
createListResource,
ListView,
ListHeader,
ListHeaderItem,
ListSelectBanner,
ListRows,
ListRow,
ListRowItem,
toast,
} from 'frappe-ui'
import { computed, ref } from 'vue'
import { Plus, Trash2 } from 'lucide-vue-next'
import EmailTemplateModal from '@/components/Modals/EmailTemplateModal.vue'
const props = defineProps({
label: {
type: String,
required: true,
},
description: {
type: String,
default: '',
},
})
const showForm = ref(false)
const readOnlyMode = window.read_only_mode
const selectedTemplate = ref(null)
const emailTemplates = createListResource({
doctype: 'Email Template',
fields: ['name', 'subject', 'use_html', 'response', 'response_html'],
auto: true,
orderBy: 'modified desc',
cache: 'email-templates',
})
const removeTemplate = (selections, unselectAll) => {
call('lms.lms.api.delete_documents', {
doctype: 'Email Template',
documents: Array.from(selections),
})
.then(() => {
emailTemplates.reload()
toast.success(__('Email Templates deleted successfully'))
unselectAll()
})
.catch((err) => {
toast.error(
cleanError(err.messages[0]) || __('Error deleting email templates')
)
})
}
const openTemplateForm = (templateID) => {
if (readOnlyMode) {
return
}
selectedTemplate.value = templateID
showForm.value = true
}
const columns = computed(() => {
return [
{
label: 'Name',
key: 'name',
width: '20rem',
},
{
label: 'Subject',
key: 'subject',
width: '25rem',
},
]
})
</script>

View File

@@ -1,5 +1,5 @@
<template> <template>
<div> <div class="flex min-h-0 flex-col text-base">
<div class="flex items-center justify-between mb-4"> <div class="flex items-center justify-between mb-4">
<div> <div>
<div class="text-xl font-semibold mb-1 text-ink-gray-9"> <div class="text-xl font-semibold mb-1 text-ink-gray-9">
@@ -39,25 +39,27 @@
</Button> </Button>
</div> </div>
<div class="divide-y"> <div class="overflow-y-scroll">
<div <div class="divide-y">
v-for="evaluator in evaluators.data" <div
@click="openProfile(evaluator.username)" v-for="evaluator in evaluators.data"
class="cursor-pointer" @click="openProfile(evaluator.username)"
> class="cursor-pointer"
<div class="flex items-center justify-between py-3"> >
<div class="flex items-center space-x-3"> <div class="flex items-center justify-between py-3">
<Avatar <div class="flex items-center space-x-3">
:image="evaluator.user_image" <Avatar
:label="evaluator.full_name" :image="evaluator.user_image"
size="lg" :label="evaluator.full_name"
/> size="lg"
<div> />
<div class="text-base font-semibold text-ink-gray-9"> <div>
{{ evaluator.full_name }} <div class="text-base font-semibold text-ink-gray-9">
</div> {{ evaluator.full_name }}
<div class="text-xs text-ink-gray-5"> </div>
{{ evaluator.evaluator }} <div class="text-xs text-ink-gray-5">
{{ evaluator.evaluator }}
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,60 +1,55 @@
<template> <template>
<div class="flex h-full flex-col"> <div class="flex h-full flex-col relative">
<div class="h-full pb-10" id="scrollContainer"> <div class="h-full pb-10" id="scrollContainer">
<slot /> <slot />
</div> </div>
<div
v-if="sidebarSettings.data" <div class="relative z-20">
class="fixed flex items-center justify-around border-t border-outline-gray-2 bottom-0 z-10 w-full bg-surface-white standalone:pb-4" <!-- Dropdown menu -->
:style="{ <div
gridTemplateColumns: `repeat(${ class="fixed bottom-16 right-2 w-[80%] rounded-md bg-surface-white text-base p-5 space-y-4 shadow-md"
sidebarLinks.length + 1 v-if="showMenu"
}, minmax(0, 1fr))`, ref="menu"
}"
>
<button
v-for="tab in sidebarLinks"
:key="tab.label"
:class="isVisible(tab) ? 'block' : 'hidden'"
class="flex flex-col items-center justify-center py-3 transition active:scale-95"
@click="handleClick(tab)"
> >
<component <div
:is="icons[tab.icon]" v-for="link in otherLinks"
class="h-6 w-6 stroke-1.5" :key="link.label"
:class="[isActive(tab) ? 'text-ink-gray-9' : 'text-ink-gray-5']" class="flex items-center space-x-2 cursor-pointer"
/> @click="handleClick(link)"
</button> >
<Popover <component
trigger="hover" :is="icons[link.icon]"
popoverClass="bottom-28 mx-2" class="h-4 w-4 stroke-1.5 text-ink-gray-5"
placement="top-start" />
<div>{{ link.label }}</div>
</div>
</div>
<!-- Fixed menu -->
<div
v-if="sidebarSettings.data"
class="fixed bottom-0 left-0 w-full flex items-center justify-around border-t border-outline-gray-2 bg-surface-white standalone:pb-4 z-10"
> >
<template #target> <button
v-for="tab in sidebarLinks"
:key="tab.label"
:class="isVisible(tab) ? 'block' : 'hidden'"
class="flex flex-col items-center justify-center py-3 transition active:scale-95"
@click="handleClick(tab)"
>
<component
:is="icons[tab.icon]"
class="h-6 w-6 stroke-1.5"
:class="[isActive(tab) ? 'text-ink-gray-9' : 'text-ink-gray-5']"
/>
</button>
<button @click="toggleMenu">
<component <component
:is="icons['List']" :is="icons['List']"
class="h-6 w-6 stroke-1.5 text-ink-gray-5" class="h-6 w-6 stroke-1.5 text-ink-gray-5"
/> />
</template> </button>
<template #body-main> </div>
<div class="text-base p-5 space-y-4">
<div
v-for="link in otherLinks"
:key="link.label"
class="flex items-center space-x-2"
@click="handleClick(link)"
>
<component
:is="icons[link.icon]"
class="h-4 w-4 stroke-1.5 text-ink-gray-5"
/>
<div>
{{ link.label }}
</div>
</div>
</div>
</template>
</Popover>
</div> </div>
</div> </div>
</template> </template>
@@ -64,7 +59,6 @@ import { useRouter } from 'vue-router'
import { watch, ref, onMounted } from 'vue' import { watch, ref, onMounted } from 'vue'
import { sessionStore } from '@/stores/session' import { sessionStore } from '@/stores/session'
import { usersStore } from '@/stores/user' import { usersStore } from '@/stores/user'
import { Popover } from 'frappe-ui'
import * as icons from 'lucide-vue-next' import * as icons from 'lucide-vue-next'
const { logout, user, sidebarSettings } = sessionStore() const { logout, user, sidebarSettings } = sessionStore()
@@ -73,26 +67,47 @@ const router = useRouter()
let { userResource } = usersStore() let { userResource } = usersStore()
const sidebarLinks = ref(getSidebarLinks()) const sidebarLinks = ref(getSidebarLinks())
const otherLinks = ref([]) const otherLinks = ref([])
const showMenu = ref(false)
const menu = ref(null)
onMounted(() => { onMounted(() => {
sidebarSettings.reload( sidebarSettings.reload(
{}, {},
{ {
onSuccess(data) { onSuccess(data) {
Object.keys(data).forEach((key) => { filterLinksToShow(data)
if (!parseInt(data[key])) {
sidebarLinks.value = sidebarLinks.value.filter(
(link) => link.label.toLowerCase().split(' ').join('_') !== key
)
}
})
addOtherLinks() addOtherLinks()
}, },
} }
) )
}) })
const handleOutsideClick = (e) => {
if (menu.value && !menu.value.contains(e.target)) {
showMenu.value = false
}
}
watch(showMenu, (val) => {
if (val) {
setTimeout(() => {
document.addEventListener('click', handleOutsideClick)
}, 0)
} else {
document.removeEventListener('click', handleOutsideClick)
}
})
const filterLinksToShow = (data) => {
Object.keys(data).forEach((key) => {
if (!parseInt(data[key])) {
sidebarLinks.value = sidebarLinks.value.filter(
(link) => link.label.toLowerCase().split(' ').join('_') !== key
)
}
})
}
const addOtherLinks = () => { const addOtherLinks = () => {
if (user) { if (user) {
otherLinks.value.push({ otherLinks.value.push({
@@ -122,6 +137,7 @@ watch(userResource, () => {
(userResource.data.is_moderator || userResource.data.is_instructor) (userResource.data.is_moderator || userResource.data.is_instructor)
) { ) {
addQuizzes() addQuizzes()
addAssignments()
} }
}) })
@@ -133,6 +149,14 @@ const addQuizzes = () => {
}) })
} }
const addAssignments = () => {
otherLinks.value.push({
label: 'Assignments',
icon: 'Pencil',
to: 'Assignments',
})
}
let isActive = (tab) => { let isActive = (tab) => {
return tab.activeFor?.includes(router.currentRoute.value.name) return tab.activeFor?.includes(router.currentRoute.value.name)
} }
@@ -158,4 +182,8 @@ const isVisible = (tab) => {
else if (tab.label == 'Log out') return isLoggedIn else if (tab.label == 'Log out') return isLoggedIn
else return true else return true
} }
const toggleMenu = () => {
showMenu.value = !showMenu.value
}
</script> </script>

View File

@@ -6,7 +6,7 @@
}" }"
> >
<template #body> <template #body>
<div class="p-5 text-base max-h-[75vh] overflow-y-auto"> <div class="p-5 text-base">
<div class="text-lg text-ink-gray-9 font-semibold mb-5"> <div class="text-lg text-ink-gray-9 font-semibold mb-5">
{{ {{
assignmentID === 'new' assignmentID === 'new'
@@ -14,7 +14,7 @@
: __('Edit Assignment') : __('Edit Assignment')
}} }}
</div> </div>
<div class="space-y-4"> <div class="space-y-4 max-h-[75vh] overflow-y-auto">
<FormControl <FormControl
v-model="assignment.title" v-model="assignment.title"
:label="__('Title')" :label="__('Title')"

View File

@@ -0,0 +1,192 @@
<template>
<Dialog
v-model="show"
:options="{
title:
templateID == 'new'
? __('New Email Template')
: __('Edit Email Template'),
size: 'lg',
actions: [
{
label: __('Save'),
variant: 'solid',
onClick: ({ close }) => {
saveTemplate(close)
},
},
],
}"
>
<template #body-content>
<div class="space-y-4">
<FormControl
:label="__('Name')"
v-model="template.name"
type="text"
:required="true"
:placeholder="__('Batch Enrollment Confirmation')"
/>
<FormControl
:label="__('Subject')"
v-model="template.subject"
type="text"
:required="true"
:placeholder="__('Your enrollment in {{ batch_name }} is confirmed')"
/>
<FormControl
:label="__('Use HTML')"
v-model="template.use_html"
type="checkbox"
/>
<FormControl
v-if="template.use_html"
:label="__('Content')"
v-model="template.response_html"
type="textarea"
:required="true"
:rows="10"
:placeholder="
__(
'<p>Dear {{ member_name }},</p>\n\n<p>You have been enrolled in our upcoming batch {{ batch_name }}.</p>\n\n<p>Thanks,</p>\n<p>Frappe Learning</p>'
)
"
/>
<div v-else>
<div class="text-xs text-ink-gray-5 mb-2">
{{ __('Content') }}
<span class="text-ink-red-3">*</span>
</div>
<TextEditor
:content="template.response"
@change="(val) => (template.response = val)"
:editable="true"
:fixedMenu="true"
:placeholder="
__(
'Dear {{ member_name }},\n\nYou have been enrolled in our upcoming batch {{ batch_name }}.\n\nThanks,\nFrappe Learning'
)
"
editorClass="prose-sm max-w-none border-b border-x bg-surface-gray-2 rounded-b-md py-1 px-2 min-h-[7rem] max-h-[18rem] overflow-y-auto"
/>
</div>
</div>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { call, Dialog, FormControl, TextEditor, toast } from 'frappe-ui'
import { reactive, watch } from 'vue'
import { cleanError } from '@/utils'
const props = defineProps({
templateID: {
type: String,
default: 'new',
},
})
const show = defineModel()
const emailTemplates = defineModel('emailTemplates')
const template = reactive({
name: '',
subject: '',
use_html: false,
response: '',
response_html: '',
})
const saveTemplate = (close) => {
if (props.templateID == 'new') {
createNewTemplate(close)
} else {
updateTemplate(close)
}
}
const createNewTemplate = (close) => {
emailTemplates.value.insert.submit(
{
__newname: template.name,
...template,
},
{
onSuccess() {
emailTemplates.value.reload()
refreshForm(close)
toast.success(__('Email Template created successfully'))
},
onError(err) {
refreshForm(close)
toast.error(
cleanError(err.messages[0]) || __('Error creating email template')
)
},
}
)
}
const updateTemplate = async (close) => {
if (props.templateID != template.name) {
await renameDoc()
}
setValue(close)
}
const setValue = (close) => {
emailTemplates.value.setValue.submit(
{
...template,
name: template.name,
},
{
onSuccess() {
emailTemplates.value.reload()
refreshForm(close)
toast.success(__('Email Template updated successfully'))
},
onError(err) {
refreshForm(close)
toast.error(
cleanError(err.messages[0]) || __('Error updating email template')
)
},
}
)
}
const renameDoc = async () => {
await call('frappe.client.rename_doc', {
doctype: 'Email Template',
old_name: props.templateID,
new_name: template.name,
})
}
watch(
() => props.templateID,
(val) => {
if (val !== 'new') {
emailTemplates.value?.data.forEach((row) => {
if (row.name === val) {
template.name = row.name
template.subject = row.subject
template.use_html = row.use_html
template.response = row.response
template.response_html = row.response_html
}
})
}
},
{ flush: 'post' }
)
const refreshForm = (close) => {
close()
template.name = ''
template.subject = ''
template.use_html = false
template.response = ''
template.response_html = ''
}
</script>

View File

@@ -66,7 +66,7 @@
</Dialog> </Dialog>
</template> </template>
<script setup> <script setup>
import { Dialog, createResource, Select, FormControl } from 'frappe-ui' import { Dialog, createResource, Select, FormControl, toast } from 'frappe-ui'
import { reactive, watch, inject } from 'vue' import { reactive, watch, inject } from 'vue'
import { formatTime } from '@/utils/' import { formatTime } from '@/utils/'
@@ -90,7 +90,7 @@ const props = defineProps({
}, },
}) })
let evaluation = reactive({ const evaluation = reactive({
course: '', course: '',
date: '', date: '',
start_time: '', start_time: '',
@@ -139,7 +139,7 @@ function submitEvaluation(close) {
close() close()
}, },
onError(err) { onError(err) {
let message = err.messages?.[0] || err const message = err.messages?.[0] || err
let unavailabilityMessage let unavailabilityMessage
if (typeof message === 'string') { if (typeof message === 'string') {
@@ -148,13 +148,13 @@ function submitEvaluation(close) {
unavailabilityMessage = false unavailabilityMessage = false
} }
toast.warning(__('Evaluator is unavailable')) toast.warning(__(unavailabilityMessage || 'Evaluator is unavailable'))
}, },
}) })
} }
const getCourses = () => { const getCourses = () => {
let courses = [] const courses = []
for (const course of props.courses) { for (const course of props.courses) {
if (course.evaluator) { if (course.evaluator) {
courses.push({ courses.push({
@@ -164,7 +164,7 @@ const getCourses = () => {
} }
} }
if (courses.length == 1) { if (courses.length === 1) {
evaluation.course = courses[0].value evaluation.course = courses[0].value
} }

View File

@@ -0,0 +1,115 @@
<template>
<Dialog
v-model="show"
:options="{
size: '4xl',
}"
>
<template #body>
<div class="p-5 min-h-[300px]">
<div class="text-lg font-semibold mb-4">
{{ __('Training Feedback') }}
</div>
<ListView
:columns="feedbackColumns"
:rows="feedbackList"
row-key="name"
:options="{
showTooltip: false,
rowHeight: 'h-16',
selectable: false,
}"
>
<ListHeader
class="mb-2 grid items-center space-x-4 rounded bg-surface-gray-2 p-2"
></ListHeader>
<ListRows>
<ListRow
:row="row"
v-for="row in feedbackList"
class="group feedback-list"
>
<template #default="{ column, item }">
<ListRowItem
:item="row[column.key]"
:align="column.align"
class="text-sm"
>
<template #prefix>
<div v-if="column.key == 'member_name'">
<Avatar
class="flex"
:image="row['member_image']"
:label="item"
size="sm"
/>
</div>
</template>
<div v-if="ratingKeys.includes(column.key)">
<Rating v-model="row[column.key]" :readonly="true" />
</div>
<div v-else class="leading-5">
{{ row[column.key] }}
</div>
</ListRowItem>
</template>
</ListRow>
</ListRows>
</ListView>
</div>
</template>
</Dialog>
</template>
<script setup lang="ts">
import {
Dialog,
ListView,
Avatar,
ListHeader,
ListRows,
ListRow,
ListRowItem,
Rating,
} from 'frappe-ui'
import { reactive, computed } from 'vue'
const show = defineModel()
const ratingKeys = ['content', 'instructors', 'value']
const props = defineProps({
feedbackList: {
type: Array,
required: true,
},
})
const feedbackColumns = computed(() => {
return [
{
label: 'Member',
key: 'member_name',
width: '10rem',
},
{
label: 'Feedback',
key: 'feedback',
width: '15rem',
},
{
label: 'Content',
key: 'content',
width: '9rem',
},
{
label: 'Instructors',
key: 'instructors',
width: '9rem',
},
{
label: 'Value',
key: 'value',
width: '9rem',
},
]
})
</script>

View File

@@ -15,26 +15,20 @@
> >
<template #body-content> <template #body-content>
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<div> <Rating v-model="review.rating" :label="__('Rating')" />
<div class="mb-1.5 text-sm text-ink-gray-5"> <FormControl
{{ __('Rating') }} :label="__('Review')"
</div> type="textarea"
<Rating v-model="review.rating" /> v-model="review.review"
</div> :rows="5"
<div> />
<div class="mb-1.5 text-sm text-ink-gray-5">
{{ __('Review') }}
</div>
<Textarea type="text" size="md" rows="5" v-model="review.review" />
</div>
</div> </div>
</template> </template>
</Dialog> </Dialog>
</template> </template>
<script setup> <script setup>
import { Dialog, Textarea, createResource, toast } from 'frappe-ui' import { Dialog, FormControl, createResource, toast, Rating } from 'frappe-ui'
import { reactive } from 'vue' import { reactive } from 'vue'
import Rating from '@/components/Controls/Rating.vue'
const show = defineModel() const show = defineModel()
const reviews = defineModel('reloadReviews') const reviews = defineModel('reloadReviews')

View File

@@ -51,6 +51,11 @@
:label="activeTab.label" :label="activeTab.label"
:description="activeTab.description" :description="activeTab.description"
/> />
<EmailTemplates
v-else-if="activeTab.label === 'Email Templates'"
:label="activeTab.label"
:description="activeTab.description"
/>
<PaymentSettings <PaymentSettings
v-else-if="activeTab.label === 'Payment Gateway'" v-else-if="activeTab.label === 'Payment Gateway'"
:label="activeTab.label" :label="activeTab.label"
@@ -86,6 +91,7 @@ import SidebarLink from '@/components/SidebarLink.vue'
import Members from '@/components/Members.vue' import Members from '@/components/Members.vue'
import Evaluators from '@/components/Evaluators.vue' import Evaluators from '@/components/Evaluators.vue'
import Categories from '@/components/Categories.vue' import Categories from '@/components/Categories.vue'
import EmailTemplates from '@/components/EmailTemplates.vue'
import BrandSettings from '@/components/BrandSettings.vue' import BrandSettings from '@/components/BrandSettings.vue'
import PaymentSettings from '@/components/PaymentSettings.vue' import PaymentSettings from '@/components/PaymentSettings.vue'
@@ -122,7 +128,7 @@ const tabsStructure = computed(() => {
label: 'Enable Learning Paths', label: 'Enable Learning Paths',
name: 'enable_learning_paths', name: 'enable_learning_paths',
description: description:
'This will enforce students to go through programs assigned to them in the correct order.', 'This will ensure students follow the assigned programs in order.',
type: 'checkbox', type: 'checkbox',
}, },
{ {
@@ -139,11 +145,26 @@ const tabsStructure = computed(() => {
'If enabled, it sends google calendar invite to the student for evaluations.', 'If enabled, it sends google calendar invite to the student for evaluations.',
type: 'checkbox', type: 'checkbox',
}, },
{
type: 'Column Break',
},
{
label: 'Batch Confirmation Template',
name: 'batch_confirmation_template',
doctype: 'Email Template',
type: 'Link',
},
{
label: 'Certification Template',
name: 'certification_template',
doctype: 'Email Template',
type: 'Link',
},
{ {
label: 'Unsplash Access Key', label: 'Unsplash Access Key',
name: 'unsplash_access_key', name: 'unsplash_access_key',
description: description:
'Optional. If this is set, students can pick a cover image from the unsplash library for their profile page. https://unsplash.com/documentation#getting-started.', 'Allows users to pick a profile cover image from Unsplash. https://unsplash.com/documentation#getting-started.',
type: 'password', type: 'password',
}, },
], ],
@@ -160,6 +181,12 @@ const tabsStructure = computed(() => {
description: description:
'Configure the payment gateway and other payment related settings', 'Configure the payment gateway and other payment related settings',
fields: [ fields: [
{
label: 'Default Currency',
name: 'default_currency',
type: 'Link',
doctype: 'Currency',
},
{ {
label: 'Payment Gateway', label: 'Payment Gateway',
name: 'payment_gateway', name: 'payment_gateway',
@@ -167,10 +194,7 @@ const tabsStructure = computed(() => {
doctype: 'Payment Gateway', doctype: 'Payment Gateway',
}, },
{ {
label: 'Default Currency', type: 'Column Break',
name: 'default_currency',
type: 'Link',
doctype: 'Currency',
}, },
{ {
label: 'Apply GST for India', label: 'Apply GST for India',
@@ -207,9 +231,14 @@ const tabsStructure = computed(() => {
}, },
{ {
label: 'Categories', label: 'Categories',
description: 'Manage the members of your learning system', description: 'Double click to edit the category',
icon: 'Network', icon: 'Network',
}, },
{
label: 'Email Templates',
description: 'Manage the email templates for your learning system',
icon: 'MailPlus',
},
], ],
}, },
{ {
@@ -235,28 +264,6 @@ const tabsStructure = computed(() => {
name: 'favicon', name: 'favicon',
type: 'Upload', type: 'Upload',
}, },
{
label: 'Footer Logo',
name: 'footer_logo',
type: 'Upload',
},
{
label: 'Address',
name: 'address',
type: 'textarea',
rows: 2,
},
{
label: 'Footer "Powered By"',
name: 'footer_powered',
type: 'textarea',
rows: 4,
},
{
label: 'Copyright',
name: 'copyright',
type: 'text',
},
], ],
}, },
{ {
@@ -299,24 +306,6 @@ const tabsStructure = computed(() => {
}, },
], ],
}, },
{
label: 'Email Templates',
icon: 'MailPlus',
fields: [
{
label: 'Batch Confirmation Template',
name: 'batch_confirmation_template',
doctype: 'Email Template',
type: 'Link',
},
{
label: 'Certification Template',
name: 'certification_template',
doctype: 'Email Template',
type: 'Link',
},
],
},
{ {
label: 'Signup', label: 'Signup',
icon: 'LogIn', icon: 'LogIn',

View File

@@ -12,13 +12,13 @@
/> --> /> -->
</div> </div>
<div class="overflow-y-scroll"> <div class="overflow-y-scroll">
<div class="flex space-x-4"> <div class="flex flex-col divide-y">
<SettingFields :fields="fields" :data="data.doc" class="w-1/2" /> <SettingFields :fields="fields" :data="data.doc" />
<SettingFields <SettingFields
v-if="paymentGateway.data" v-if="paymentGateway.data"
:fields="paymentGateway.data.fields" :fields="paymentGateway.data.fields"
:data="paymentGateway.data.data" :data="paymentGateway.data.data"
class="w-1/2" class="pt-5 my-0"
/> />
</div> </div>
</div> </div>
@@ -60,9 +60,28 @@ const paymentGateway = createResource({
payment_gateway: props.data.doc.payment_gateway, payment_gateway: props.data.doc.payment_gateway,
} }
}, },
transform(data) {
arrangeFields(data.fields)
return data
},
auto: true, auto: true,
}) })
const arrangeFields = (fields) => {
fields = fields.sort((a, b) => {
if (a.type === 'Upload' && b.type !== 'Upload') {
return 1
} else if (a.type !== 'Upload' && b.type === 'Upload') {
return -1
}
return 0
})
fields.splice(3, 0, {
type: 'Column Break',
})
}
const saveSettings = createResource({ const saveSettings = createResource({
url: 'frappe.client.set_value', url: 'frappe.client.set_value',
makeParams(values) { makeParams(values) {

View File

@@ -6,7 +6,7 @@
<div v-for="(column, index) in columns" :key="index"> <div v-for="(column, index) in columns" :key="index">
<div <div
class="flex flex-col space-y-5" class="flex flex-col space-y-5"
:class="columns.length > 1 ? 'w-72' : 'w-full'" :class="columns.length > 1 ? 'w-[21rem]' : 'w-1/2'"
> >
<div v-for="field in column"> <div v-for="field in column">
<Link <Link
@@ -14,6 +14,7 @@
v-model="data[field.name]" v-model="data[field.name]"
:doctype="field.doctype" :doctype="field.doctype"
:label="__(field.label)" :label="__(field.label)"
:description="__(field.description)"
/> />
<div v-else-if="field.type == 'Code'"> <div v-else-if="field.type == 'Code'">
@@ -54,11 +55,11 @@
<div v-else> <div v-else>
<div class="flex items-center text-sm space-x-2"> <div class="flex items-center text-sm space-x-2">
<div <div
class="flex items-center justify-center rounded border border-outline-gray-modals bg-white w-[10rem] py-2" class="flex items-center justify-center rounded border border-outline-gray-1 bg-surface-gray-2 px-20 py-5"
> >
<img <img
:src="data[field.name]?.file_url || data[field.name]" :src="data[field.name]?.file_url || data[field.name]"
class="w-[80%] rounded" class="size-6 rounded"
/> />
</div> </div>
<div class="flex flex-col flex-wrap"> <div class="flex flex-col flex-wrap">

View File

@@ -88,56 +88,61 @@
:scrollToBottom="false" :scrollToBottom="false"
/> />
</div> </div>
<div v-else-if="tab.label == 'Feedback'">
<BatchFeedback :batch="batch.data.name" />
</div>
</div> </div>
</template> </template>
</Tabs> </Tabs>
</div> </div>
<div class="p-5"> <div class="p-5">
<div class="text-ink-gray-7 font-semibold mb-4"> <div class="mb-10">
{{ __('About this batch') }}: <div class="text-ink-gray-7 font-semibold mb-2">
</div> {{ __('About this batch') }}
<div </div>
v-html="batch.data.description" <div
class="leading-5 mb-4 text-ink-gray-7" v-html="batch.data.description"
></div> class="leading-5 mb-4 text-ink-gray-7"
></div>
<div class="flex items-center avatar-group overlap mb-5">
<div <div class="flex items-center avatar-group overlap mb-5">
class="h-6 mr-1" <div
:class="{ class="h-6 mr-1"
'avatar-group overlap': batch.data.instructors.length > 1, :class="{
}" 'avatar-group overlap': batch.data.instructors.length > 1,
> }"
<UserAvatar >
v-for="instructor in batch.data.instructors" <UserAvatar
:user="instructor" v-for="instructor in batch.data.instructors"
/> :user="instructor"
/>
</div>
<CourseInstructors :instructors="batch.data.instructors" />
</div>
<DateRange
:startDate="batch.data.start_date"
:endDate="batch.data.end_date"
class="mb-3"
/>
<div class="flex items-center mb-4 text-ink-gray-7">
<Clock class="h-4 w-4 stroke-1.5 mr-2" />
<span>
{{ formatTime(batch.data.start_time) }} -
{{ formatTime(batch.data.end_time) }}
</span>
</div>
<div
v-if="batch.data.timezone"
class="flex items-center mb-4 text-ink-gray-7"
>
<Globe class="h-4 w-4 stroke-1.5 mr-2" />
<span>
{{ batch.data.timezone }}
</span>
</div> </div>
<CourseInstructors :instructors="batch.data.instructors" />
</div> </div>
<DateRange <div v-if="dayjs().isSameOrAfter(dayjs(batch.data.start_date))">
:startDate="batch.data.start_date" <div class="text-ink-gray-7 font-semibold mb-2">
:endDate="batch.data.end_date" {{ __('Feedback') }}
class="mb-3" </div>
/> <BatchFeedback :batch="batch.data?.name" />
<div class="flex items-center mb-4 text-ink-gray-7">
<Clock class="h-4 w-4 stroke-1.5 mr-2" />
<span>
{{ formatTime(batch.data.start_time) }} -
{{ formatTime(batch.data.end_time) }}
</span>
</div>
<div
v-if="batch.data.timezone"
class="flex items-center mb-4 text-ink-gray-7"
>
<Globe class="h-4 w-4 stroke-1.5 mr-2" />
<span>
{{ batch.data.timezone }}
</span>
</div> </div>
</div> </div>
<AnnouncementModal <AnnouncementModal
@@ -234,6 +239,7 @@ import Discussions from '@/components/Discussions.vue'
import DateRange from '@/components/Common/DateRange.vue' import DateRange from '@/components/Common/DateRange.vue'
import BulkCertificates from '@/components/Modals/BulkCertificates.vue' import BulkCertificates from '@/components/Modals/BulkCertificates.vue'
import BatchFeedback from '@/components/BatchFeedback.vue' import BatchFeedback from '@/components/BatchFeedback.vue'
import dayjs from 'dayjs/esm'
const user = inject('$user') const user = inject('$user')
const showAnnouncementModal = ref(false) const showAnnouncementModal = ref(false)
@@ -277,11 +283,6 @@ const tabs = computed(() => {
label: 'Discussions', label: 'Discussions',
icon: MessageCircle, icon: MessageCircle,
}) })
batchTabs.push({
label: 'Feedback',
icon: ClipboardPen,
})
return batchTabs return batchTabs
}) })

View File

@@ -37,14 +37,7 @@
<BatchOverlay :batch="batch" /> <BatchOverlay :batch="batch" />
</div> </div>
</div> </div>
<!-- <div class="grid lg:grid-cols-[60%,20%] gap-4 lg:gap-20 mt-10"> <BatchOverlay :batch="batch" class="md:hidden mt-5" />
<div class="order-2 lg:order-none">
</div>
<div class="order-1 lg:order-none">
<BatchOverlay :batch="batch" />
</div>
</div> -->
<div v-if="batch.data.courses.length"> <div v-if="batch.data.courses.length">
<div class="flex items-center mt-10"> <div class="flex items-center mt-10">
<div class="text-2xl font-semibold"> <div class="text-2xl font-semibold">

View File

@@ -153,6 +153,11 @@
doctype="Email Template" doctype="Email Template"
:label="__('Email Template')" :label="__('Email Template')"
v-model="batch.confirmation_email_template" v-model="batch.confirmation_email_template"
:onCreate="
(value, close) => {
openSettings('Email Templates', close)
}
"
/> />
</div> </div>
<div class="space-y-5"> <div class="space-y-5">

View File

@@ -20,14 +20,12 @@
</header> </header>
<div class="p-5 pb-10"> <div class="p-5 pb-10">
<div <div
v-if="batchCount"
class="flex flex-col lg:flex-row space-y-4 lg:space-y-0 lg:items-center justify-between mb-5" class="flex flex-col lg:flex-row space-y-4 lg:space-y-0 lg:items-center justify-between mb-5"
> >
<div class="text-lg text-ink-gray-9 font-semibold"> <div class="text-lg text-ink-gray-9 font-semibold">
{{ __('All Batches') }} {{ __('All Batches') }}
</div> </div>
<div <div
v-if="batches.data?.length || batchCount"
class="flex flex-col space-y-2 lg:space-y-0 lg:flex-row lg:items-center lg:space-x-4" class="flex flex-col space-y-2 lg:space-y-0 lg:flex-row lg:items-center lg:space-x-4"
> >
<TabButtons <TabButtons
@@ -115,12 +113,10 @@ const is_student = computed(() => user.data?.is_student)
const currentTab = ref(is_student.value ? 'All' : 'Upcoming') const currentTab = ref(is_student.value ? 'All' : 'Upcoming')
const orderBy = ref('start_date') const orderBy = ref('start_date')
const readOnlyMode = window.read_only_mode const readOnlyMode = window.read_only_mode
const batchCount = ref(0)
onMounted(() => { onMounted(() => {
setFiltersFromQuery() setFiltersFromQuery()
updateBatches() updateBatches()
getBatchCount()
categories.value = [ categories.value = [
{ {
label: '', label: '',
@@ -298,14 +294,6 @@ const canCreateBatch = () => {
return false return false
} }
const getBatchCount = () => {
call('frappe.client.get_count', {
doctype: 'LMS Batch',
}).then((data) => {
batchCount.value = data
})
}
const breadcrumbs = computed(() => [ const breadcrumbs = computed(() => [
{ {
label: __('Batches'), label: __('Batches'),

View File

@@ -20,7 +20,7 @@
: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="size-4 text-transparent fill-yellow-500" />
<span class="ml-1 text-ink-gray-7"> <span class="ml-1 text-ink-gray-7">
{{ course.data.rating }} {{ course.data.rating }}
</span> </span>

View File

@@ -20,14 +20,12 @@
</header> </header>
<div class="p-5 pb-10"> <div class="p-5 pb-10">
<div <div
v-if="courseCount"
class="flex flex-col lg:flex-row space-y-4 lg:space-y-0 lg:items-center justify-between mb-5" class="flex flex-col lg:flex-row space-y-4 lg:space-y-0 lg:items-center justify-between mb-5"
> >
<div class="text-lg text-ink-gray-9 font-semibold"> <div class="text-lg text-ink-gray-9 font-semibold">
{{ __('All Courses') }} {{ __('All Courses') }}
</div> </div>
<div <div
v-if="courses.data?.length || courseCount"
class="flex flex-col space-y-2 lg:space-y-0 lg:flex-row lg:items-center lg:space-x-4" class="flex flex-col space-y-2 lg:space-y-0 lg:flex-row lg:items-center lg:space-x-4"
> >
<TabButtons :buttons="courseTabs" v-model="currentTab" /> <TabButtons :buttons="courseTabs" v-model="currentTab" />
@@ -172,6 +170,8 @@ const identifyUserPersona = async () => {
} }
const getCourseCount = () => { const getCourseCount = () => {
if (!user.data) return
call('frappe.client.get_count', { call('frappe.client.get_count', {
doctype: 'LMS Course', doctype: 'LMS Course',
}).then((data) => { }).then((data) => {

View File

@@ -561,3 +561,24 @@ export const openSettings = (category, close) => {
settingsStore.activeTab = category settingsStore.activeTab = category
settingsStore.isSettingsOpen = true settingsStore.isSettingsOpen = true
} }
export const cleanError = (message) => {
// Remove HTML tags but keep the text within the tags
const cleanMessage = message.replace(/<[^>]+>/g, (match) => {
return match.replace(/<\/?[^>]+(>|$)/g, '')
})
return cleanMessage
.replace(/&nbsp;/g, ' ')
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&quot;/g, '"')
.replace(/&#39;/g, "'")
.replace(/&amp;/g, '&')
.replace(/&#x60;/g, '`')
.replace(/&#x3D;/g, '=')
.replace(/&#x2F;/g, '/')
.replace(/&#x2C;/g, ',')
.replace(/&#x3B;/g, ';')
.replace(/&#x3A;/g, ':')
}

View File

@@ -356,6 +356,7 @@
"fieldtype": "Section Break" "fieldtype": "Section Break"
} }
], ],
"grid_page_length": 50,
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"links": [ "links": [
{ {
@@ -371,8 +372,8 @@
"link_fieldname": "batch_name" "link_fieldname": "batch_name"
} }
], ],
"modified": "2025-02-18 15:43:18.512504", "modified": "2025-05-21 13:30:28.904260",
"modified_by": "Administrator", "modified_by": "sayali@frappe.io",
"module": "LMS", "module": "LMS",
"name": "LMS Batch", "name": "LMS Batch",
"owner": "Administrator", "owner": "Administrator",
@@ -412,12 +413,22 @@
"role": "Batch Evaluator", "role": "Batch Evaluator",
"share": 1, "share": 1,
"write": 1 "write": 1
},
{
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "LMS Student",
"share": 1
} }
], ],
"row_format": "Dynamic",
"show_title_field_in_link": 1, "show_title_field_in_link": 1,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"states": [], "states": [],
"title_field": "title", "title_field": "title",
"track_changes": 1 "track_changes": 1
} }

View File

@@ -103,7 +103,7 @@ class LMSBatch(Document):
frappe.throw(_("Seat count cannot be negative.")) frappe.throw(_("Seat count cannot be negative."))
students = frappe.db.count("LMS Batch Enrollment", {"batch": self.name}) students = frappe.db.count("LMS Batch Enrollment", {"batch": self.name})
if cint(self.seat_count) < students: if cint(self.seat_count) and cint(self.seat_count) < students:
frappe.throw(_("There are no seats available in this batch.")) frappe.throw(_("There are no seats available in this batch."))
def validate_timetable(self): def validate_timetable(self):

View File

@@ -73,10 +73,11 @@
"read_only": 1 "read_only": 1
} }
], ],
"grid_page_length": 50,
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"links": [], "links": [],
"modified": "2025-01-13 19:02:58.259908", "modified": "2025-05-21 15:58:51.667270",
"modified_by": "Administrator", "modified_by": "sayali@frappe.io",
"module": "LMS", "module": "LMS",
"name": "LMS Batch Feedback", "name": "LMS Batch Feedback",
"owner": "Administrator", "owner": "Administrator",
@@ -106,7 +107,9 @@
"write": 1 "write": 1
} }
], ],
"row_format": "Dynamic",
"sort_field": "creation", "sort_field": "creation",
"sort_order": "DESC", "sort_order": "DESC",
"states": [] "states": [],
} "title_field": "member"
}

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: 2025-05-16 16:04+0000\n" "POT-Creation-Date: 2025-05-23 16:04+0000\n"
"PO-Revision-Date: 2025-05-16 16:04+0000\n" "PO-Revision-Date: 2025-05-23 16:04+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"
@@ -50,6 +50,10 @@ msgstr ""
msgid "<a href=\"https://docs.frappe.io/learning\">Documentation</a>" msgid "<a href=\"https://docs.frappe.io/learning\">Documentation</a>"
msgstr "" msgstr ""
#: frontend/src/components/Modals/EmailTemplateModal.vue:50
msgid "<p>Dear {{ member_name }},</p>\\n\\n<p>You have been enrolled in our upcoming batch {{ batch_name }}.</p>\\n\\n<p>Thanks,</p>\\n<p>Frappe Learning</p>"
msgstr ""
#. Header text in the LMS Workspace #. Header text in the LMS Workspace
#: lms/lms/workspace/lms/lms.json #: lms/lms/workspace/lms/lms.json
msgid "<span class=\"h4\"><b>Get Started</b></span>" msgid "<span class=\"h4\"><b>Get Started</b></span>"
@@ -77,7 +81,7 @@ msgstr ""
msgid "About" msgid "About"
msgstr "" msgstr ""
#: frontend/src/pages/Batch.vue:100 #: frontend/src/pages/Batch.vue:98
msgid "About this batch" msgid "About this batch"
msgstr "" msgstr ""
@@ -112,7 +116,7 @@ msgstr ""
#: frontend/src/components/Assessments.vue:11 #: frontend/src/components/Assessments.vue:11
#: frontend/src/components/BatchCourses.vue:11 #: frontend/src/components/BatchCourses.vue:11
#: frontend/src/components/BatchStudents.vue:117 #: frontend/src/components/BatchStudents.vue:117
#: frontend/src/components/Categories.vue:27 #: frontend/src/components/Categories.vue:43
#: frontend/src/components/Evaluators.vue:38 #: frontend/src/components/Evaluators.vue:38
#: frontend/src/components/LiveClass.vue:11 #: frontend/src/components/LiveClass.vue:11
#: frontend/src/components/Members.vue:44 frontend/src/pages/ProgramForm.vue:30 #: frontend/src/components/Members.vue:44 frontend/src/pages/ProgramForm.vue:30
@@ -146,7 +150,7 @@ msgstr ""
msgid "Add a Student" msgid "Add a Student"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:557 #: frontend/src/components/AppSidebar.vue:553
msgid "Add a chapter" msgid "Add a chapter"
msgstr "" msgstr ""
@@ -158,7 +162,7 @@ msgstr ""
msgid "Add a keyword and then press enter" msgid "Add a keyword and then press enter"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:558 #: frontend/src/components/AppSidebar.vue:554
msgid "Add a lesson" msgid "Add a lesson"
msgstr "" msgstr ""
@@ -183,11 +187,11 @@ msgstr ""
msgid "Add at least one possible answer for this question: {0}" msgid "Add at least one possible answer for this question: {0}"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:522 #: frontend/src/components/AppSidebar.vue:518
msgid "Add courses to your batch" msgid "Add courses to your batch"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:502 #: frontend/src/components/AppSidebar.vue:498
msgid "Add students to your batch" msgid "Add students to your batch"
msgstr "" msgstr ""
@@ -199,11 +203,11 @@ msgstr ""
msgid "Add your assignment as {0}" msgid "Add your assignment as {0}"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:438 #: frontend/src/components/AppSidebar.vue:434
msgid "Add your first chapter" msgid "Add your first chapter"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:453 #: frontend/src/components/AppSidebar.vue:449
msgid "Add your first lesson" msgid "Add your first lesson"
msgstr "" msgstr ""
@@ -231,22 +235,18 @@ msgid "Admin"
msgstr "" msgstr ""
#. Name of a role #. Name of a role
#: frontend/src/pages/Batches.vue:277 lms/lms/doctype/lms_badge/lms_badge.json #: frontend/src/pages/Batches.vue:273 lms/lms/doctype/lms_badge/lms_badge.json
msgid "All" msgid "All"
msgstr "" msgstr ""
#: frontend/src/pages/Batches.vue:27 #: frontend/src/pages/Batches.vue:26
msgid "All Batches" msgid "All Batches"
msgstr "" msgstr ""
#: frontend/src/pages/Courses.vue:27 lms/lms/widgets/BreadCrumb.html:3 #: frontend/src/pages/Courses.vue:26 lms/lms/widgets/BreadCrumb.html:3
msgid "All Courses" msgid "All Courses"
msgstr "" msgstr ""
#: frontend/src/components/BatchFeedback.vue:51
msgid "All Feedback"
msgstr ""
#: lms/templates/quiz/quiz.html:141 #: lms/templates/quiz/quiz.html:141
msgid "All Submissions" msgid "All Submissions"
msgstr "" msgstr ""
@@ -286,7 +286,7 @@ msgstr ""
#. Label of the amount (Currency) field in DocType 'LMS Batch' #. Label of the amount (Currency) field in DocType 'LMS Batch'
#. Label of the course_price (Currency) field in DocType 'LMS Course' #. Label of the course_price (Currency) field in DocType 'LMS Course'
#. 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:250 frontend/src/pages/CourseForm.vue:230 #: frontend/src/pages/BatchForm.vue:255 frontend/src/pages/CourseForm.vue:230
#: 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/lms/doctype/lms_payment/lms_payment.json #: lms/lms/doctype/lms_payment/lms_payment.json
@@ -344,11 +344,11 @@ msgstr ""
msgid "Appears on the course card in the course list" msgid "Appears on the course card in the course list"
msgstr "" msgstr ""
#: frontend/src/pages/BatchForm.vue:225 #: frontend/src/pages/BatchForm.vue:230
msgid "Appears when the batch URL is shared on any online platform" msgid "Appears when the batch URL is shared on any online platform"
msgstr "" msgstr ""
#: frontend/src/pages/BatchForm.vue:206 #: frontend/src/pages/BatchForm.vue:211
msgid "Appears when the batch URL is shared on socials" msgid "Appears when the batch URL is shared on socials"
msgstr "" msgstr ""
@@ -383,7 +383,7 @@ msgstr ""
msgid "Apps" msgid "Apps"
msgstr "" msgstr ""
#: frontend/src/pages/Batches.vue:287 #: frontend/src/pages/Batches.vue:283
msgid "Archived" msgid "Archived"
msgstr "" msgstr ""
@@ -423,7 +423,7 @@ msgid "Assessment {0} has already been added to this batch."
msgstr "" msgstr ""
#. Label of the show_assessments (Check) field in DocType 'LMS Settings' #. Label of the show_assessments (Check) field in DocType 'LMS Settings'
#: frontend/src/components/AppSidebar.vue:570 #: frontend/src/components/AppSidebar.vue:566
#: frontend/src/components/Assessments.vue:5 #: frontend/src/components/Assessments.vue:5
#: frontend/src/components/BatchStudents.vue:68 #: frontend/src/components/BatchStudents.vue:68
#: frontend/src/components/BatchStudents.vue:101 #: frontend/src/components/BatchStudents.vue:101
@@ -484,7 +484,7 @@ msgstr ""
msgid "Assignment will appear at the bottom of the lesson." msgid "Assignment will appear at the bottom of the lesson."
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:574 #: frontend/src/components/AppSidebar.vue:570
#: frontend/src/pages/Assignments.vue:211 lms/www/lms.py:273 #: frontend/src/pages/Assignments.vue:211 lms/www/lms.py:273
msgid "Assignments" msgid "Assignments"
msgstr "" msgstr ""
@@ -517,15 +517,15 @@ msgstr ""
msgid "Availability updated successfully" msgid "Availability updated successfully"
msgstr "" msgstr ""
#: frontend/src/components/BatchFeedback.vue:43
msgid "Average Feedback Received"
msgstr ""
#: frontend/src/components/CourseCard.vue:55 #: frontend/src/components/CourseCard.vue:55
#: frontend/src/pages/CourseDetail.vue:20 #: frontend/src/pages/CourseDetail.vue:20
msgid "Average Rating" msgid "Average Rating"
msgstr "" msgstr ""
#: frontend/src/components/BatchFeedback.vue:38
msgid "Average of Feedback Received"
msgstr ""
#: frontend/src/pages/Lesson.vue:166 #: frontend/src/pages/Lesson.vue:166
msgid "Back to Course" msgid "Back to Course"
msgstr "" msgstr ""
@@ -589,6 +589,10 @@ msgstr ""
msgid "Batch Details Raw" msgid "Batch Details Raw"
msgstr "" msgstr ""
#: frontend/src/components/Modals/EmailTemplateModal.vue:28
msgid "Batch Enrollment Confirmation"
msgstr ""
#. Name of a role #. Name of a role
#: lms/lms/doctype/course_evaluator/course_evaluator.json #: lms/lms/doctype/course_evaluator/course_evaluator.json
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
@@ -653,7 +657,7 @@ msgid "Batch:"
msgstr "" msgstr ""
#. Label of the batches (Check) field in DocType 'LMS Settings' #. Label of the batches (Check) field in DocType 'LMS Settings'
#: frontend/src/pages/Batches.vue:311 frontend/src/pages/Batches.vue:318 #: frontend/src/pages/Batches.vue:299 frontend/src/pages/Batches.vue:306
#: lms/lms/doctype/lms_settings/lms_settings.json lms/www/lms.py:122 #: lms/lms/doctype/lms_settings/lms_settings.json lms/www/lms.py:122
msgid "Batches" msgid "Batches"
msgstr "" msgstr ""
@@ -752,19 +756,31 @@ 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:177 frontend/src/pages/Batches.vue:57 #: frontend/src/pages/BatchForm.vue:182 frontend/src/pages/Batches.vue:55
#: frontend/src/pages/CertifiedParticipants.vue:38 #: frontend/src/pages/CertifiedParticipants.vue:38
#: frontend/src/pages/CourseForm.vue:36 frontend/src/pages/Courses.vue:53 #: frontend/src/pages/CourseForm.vue:36 frontend/src/pages/Courses.vue:51
#: 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
#: lms/lms/doctype/lms_course/lms_course.json lms/templates/signup-form.html:22 #: lms/lms/doctype/lms_course/lms_course.json lms/templates/signup-form.html:22
msgid "Category" msgid "Category"
msgstr "" msgstr ""
#: frontend/src/components/Categories.vue:23 #: frontend/src/components/Categories.vue:39
msgid "Category Name" msgid "Category Name"
msgstr "" msgstr ""
#: frontend/src/components/Categories.vue:133
msgid "Category added successfully"
msgstr ""
#: frontend/src/components/Categories.vue:193
msgid "Category deleted successfully"
msgstr ""
#: frontend/src/components/Categories.vue:173
msgid "Category updated successfully"
msgstr ""
#. Label of the certificate (Link) field in DocType 'LMS Enrollment' #. Label of the certificate (Link) field in DocType 'LMS Enrollment'
#. Label of a shortcut in the LMS Workspace #. Label of a shortcut in the LMS Workspace
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json #: lms/lms/doctype/lms_enrollment/lms_enrollment.json
@@ -804,13 +820,13 @@ msgstr ""
#. Enrollment' #. Enrollment'
#. Label of a Card Break in the LMS Workspace #. Label of a Card Break in the LMS Workspace
#. Label of a Link in the LMS Workspace #. Label of a Link in the LMS Workspace
#: frontend/src/components/AppSidebar.vue:578 #: frontend/src/components/AppSidebar.vue:574
#: frontend/src/components/CourseCard.vue:115 #: frontend/src/components/CourseCard.vue:115
#: frontend/src/components/Modals/Event.vue:372 #: frontend/src/components/Modals/Event.vue:372
#: frontend/src/pages/BatchForm.vue:62 frontend/src/pages/Batches.vue:40 #: frontend/src/pages/BatchForm.vue:62 frontend/src/pages/Batches.vue:38
#: frontend/src/pages/CourseCertification.vue:10 #: frontend/src/pages/CourseCertification.vue:10
#: frontend/src/pages/CourseCertification.vue:135 #: frontend/src/pages/CourseCertification.vue:135
#: frontend/src/pages/Courses.vue:36 lms/fixtures/custom_field.json #: frontend/src/pages/Courses.vue:34 lms/fixtures/custom_field.json
#: lms/lms/doctype/certification/certification.json #: lms/lms/doctype/certification/certification.json
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json #: lms/lms/doctype/lms_enrollment/lms_enrollment.json
@@ -946,6 +962,10 @@ msgstr ""
msgid "Clearly Defined Role" msgid "Clearly Defined Role"
msgstr "" msgstr ""
#: frontend/src/components/BatchFeedback.vue:10
msgid "Click here"
msgstr ""
#: frontend/src/components/LessonHelp.vue:30 #: frontend/src/components/LessonHelp.vue:30
msgid "Click on the add icon in the editor and select Quiz from the menu. It opens up a dialog, where you can either select a quiz from the list or create a new quiz. When you select the Create New option it redirects you to the quiz creation page." msgid "Click on the add icon in the editor and select Quiz from the menu. It opens up a dialog, where you can either select a quiz from the list or create a new quiz. When you select the Create New option it redirects you to the quiz creation page."
msgstr "" msgstr ""
@@ -960,7 +980,7 @@ msgstr ""
msgid "Client Secret" msgid "Client Secret"
msgstr "" msgstr ""
#: frontend/src/components/Categories.vue:12 #: frontend/src/components/Categories.vue:27
#: frontend/src/components/Evaluators.vue:24 #: frontend/src/components/Evaluators.vue:24
#: frontend/src/components/Members.vue:24 #: frontend/src/components/Members.vue:24
msgid "Close" msgid "Close"
@@ -1197,6 +1217,8 @@ msgstr ""
#. Label of the content (Text) field in DocType 'Course Lesson' #. Label of the content (Text) field in DocType 'Course Lesson'
#. Label of the content (Rating) field in DocType 'LMS Batch Feedback' #. Label of the content (Rating) field in DocType 'LMS Batch Feedback'
#: frontend/src/components/Modals/EmailTemplateModal.vue:44
#: frontend/src/components/Modals/EmailTemplateModal.vue:57
#: frontend/src/pages/LessonForm.vue:62 #: frontend/src/pages/LessonForm.vue:62
#: lms/lms/doctype/course_lesson/course_lesson.json #: lms/lms/doctype/course_lesson/course_lesson.json
#: lms/lms/doctype/lms_batch_feedback/lms_batch_feedback.json #: lms/lms/doctype/lms_batch_feedback/lms_batch_feedback.json
@@ -1488,15 +1510,15 @@ msgstr ""
msgid "Create a Live Class" msgid "Create a Live Class"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:565 #: frontend/src/components/AppSidebar.vue:561
msgid "Create a batch" msgid "Create a batch"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:556 #: frontend/src/components/AppSidebar.vue:552
msgid "Create a course" msgid "Create a course"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:566 #: frontend/src/components/AppSidebar.vue:562
msgid "Create a live class" msgid "Create a live class"
msgstr "" msgstr ""
@@ -1504,15 +1526,15 @@ msgstr ""
msgid "Create an Assignment" msgid "Create an Assignment"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:492 #: frontend/src/components/AppSidebar.vue:488
msgid "Create your first batch" msgid "Create your first batch"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:426 #: frontend/src/components/AppSidebar.vue:422
msgid "Create your first course" msgid "Create your first course"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:471 #: frontend/src/components/AppSidebar.vue:467
msgid "Create your first quiz" msgid "Create your first quiz"
msgstr "" msgstr ""
@@ -1520,18 +1542,18 @@ msgstr ""
msgid "Created" msgid "Created"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:562 #: frontend/src/components/AppSidebar.vue:558
msgid "Creating a batch" msgid "Creating a batch"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:553 #: frontend/src/components/AppSidebar.vue:549
msgid "Creating a course" msgid "Creating a course"
msgstr "" 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:257 frontend/src/pages/CourseForm.vue:247 #: frontend/src/pages/BatchForm.vue:262 frontend/src/pages/CourseForm.vue:247
#: 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/lms/doctype/lms_payment/lms_payment.json #: lms/lms/doctype/lms_payment/lms_payment.json
@@ -1543,7 +1565,7 @@ msgstr ""
msgid "Current Lesson" msgid "Current Lesson"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:584 #: frontend/src/components/AppSidebar.vue:580
msgid "Custom Certificate Templates" msgid "Custom Certificate Templates"
msgstr "" msgstr ""
@@ -1623,6 +1645,10 @@ msgstr ""
msgid "Dear " msgid "Dear "
msgstr "" msgstr ""
#: frontend/src/components/Modals/EmailTemplateModal.vue:66
msgid "Dear {{ member_name }},\\n\\nYou have been enrolled in our upcoming batch {{ batch_name }}.\\n\\nThanks,\\nFrappe Learning"
msgstr ""
#. Label of the default_currency (Link) field in DocType 'LMS Settings' #. Label of the default_currency (Link) field in DocType 'LMS Settings'
#: lms/lms/doctype/lms_settings/lms_settings.json #: lms/lms/doctype/lms_settings/lms_settings.json
msgid "Default Currency" msgid "Default Currency"
@@ -1803,6 +1829,10 @@ msgstr ""
msgid "Edit Chapter" msgid "Edit Chapter"
msgstr "" msgstr ""
#: frontend/src/components/Modals/EmailTemplateModal.vue:8
msgid "Edit Email Template"
msgstr ""
#: frontend/src/pages/Profile.vue:72 #: frontend/src/pages/Profile.vue:72
msgid "Edit Profile" msgid "Edit Profile"
msgstr "" msgstr ""
@@ -1844,11 +1874,23 @@ msgstr ""
msgid "Email Template" msgid "Email Template"
msgstr "" msgstr ""
#: frontend/src/components/Modals/EmailTemplateModal.vue:117
msgid "Email Template created successfully"
msgstr ""
#: frontend/src/components/Modals/EmailTemplateModal.vue:146
msgid "Email Template updated successfully"
msgstr ""
#. Label of the email_templates_tab (Tab Break) field in DocType 'LMS Settings' #. Label of the email_templates_tab (Tab Break) field in DocType 'LMS Settings'
#: lms/lms/doctype/lms_settings/lms_settings.json #: lms/lms/doctype/lms_settings/lms_settings.json
msgid "Email Templates" msgid "Email Templates"
msgstr "" msgstr ""
#: frontend/src/components/EmailTemplates.vue:128
msgid "Email Templates deleted successfully"
msgstr ""
#. Label of the show_emails (Check) field in DocType 'LMS Settings' #. Label of the show_emails (Check) field in DocType 'LMS Settings'
#: lms/lms/doctype/lms_settings/lms_settings.json #: lms/lms/doctype/lms_settings/lms_settings.json
msgid "Emails" msgid "Emails"
@@ -1921,7 +1963,7 @@ msgstr ""
msgid "Enroll Now" msgid "Enroll Now"
msgstr "" msgstr ""
#: frontend/src/pages/Batches.vue:290 frontend/src/pages/Courses.vue:322 #: frontend/src/pages/Batches.vue:286 frontend/src/pages/Courses.vue:322
msgid "Enrolled" msgid "Enrolled"
msgstr "" msgstr ""
@@ -1967,10 +2009,22 @@ msgstr ""
msgid "Enter the correct answer" msgid "Enter the correct answer"
msgstr "" msgstr ""
#: frontend/src/components/Modals/EmailTemplateModal.vue:122
msgid "Error creating email template"
msgstr ""
#: lms/lms/doctype/lms_batch/lms_batch.py:193 #: lms/lms/doctype/lms_batch/lms_batch.py:193
msgid "Error creating live class. Please try again. {0}" msgid "Error creating live class. Please try again. {0}"
msgstr "" msgstr ""
#: frontend/src/components/EmailTemplates.vue:133
msgid "Error deleting email templates"
msgstr ""
#: frontend/src/components/Modals/EmailTemplateModal.vue:151
msgid "Error updating email template"
msgstr ""
#. Label of a Link in the LMS Workspace #. Label of a Link in the LMS Workspace
#. Label of a shortcut in the LMS Workspace #. Label of a shortcut in the LMS Workspace
#: frontend/src/components/Modals/Event.vue:365 lms/lms/workspace/lms/lms.json #: frontend/src/components/Modals/Event.vue:365 lms/lms/workspace/lms/lms.json
@@ -2043,10 +2097,6 @@ msgstr ""
msgid "Evaluator is required for paid certificates." msgid "Evaluator is required for paid certificates."
msgstr "" msgstr ""
#: frontend/src/components/Modals/EvaluationModal.vue:151
msgid "Evaluator is unavailable"
msgstr ""
#. Label of the event (Select) field in DocType 'LMS Badge' #. Label of the event (Select) field in DocType 'LMS Badge'
#. Label of the event (Link) field in DocType 'LMS Live Class' #. Label of the event (Link) field in DocType 'LMS Live Class'
#: lms/lms/doctype/lms_badge/lms_badge.json #: lms/lms/doctype/lms_badge/lms_badge.json
@@ -2135,7 +2185,8 @@ msgid "Featured"
msgstr "" msgstr ""
#. Label of the feedback (Small Text) field in DocType 'LMS Batch Feedback' #. Label of the feedback (Small Text) field in DocType 'LMS Batch Feedback'
#: frontend/src/components/BatchFeedback.vue:29 #: frontend/src/components/BatchFeedback.vue:30
#: frontend/src/pages/Batch.vue:143
#: lms/lms/doctype/lms_batch_feedback/lms_batch_feedback.json #: lms/lms/doctype/lms_batch_feedback/lms_batch_feedback.json
msgid "Feedback" msgid "Feedback"
msgstr "" msgstr ""
@@ -2336,14 +2387,14 @@ msgstr ""
msgid "Help" msgid "Help"
msgstr "" msgstr ""
#: frontend/src/components/BatchFeedback.vue:11
msgid "Help Us Improve"
msgstr ""
#: lms/templates/courses_created.html:15 #: lms/templates/courses_created.html:15
msgid "Help others learn something new by creating a course." msgid "Help others learn something new by creating a course."
msgstr "" msgstr ""
#: frontend/src/components/BatchFeedback.vue:15
msgid "Help us improve by providing your feedback."
msgstr ""
#: lms/templates/reviews.html:101 #: lms/templates/reviews.html:101
msgid "Help us improve our course material." msgid "Help us improve our course material."
msgstr "" msgstr ""
@@ -2585,8 +2636,8 @@ msgstr ""
msgid "Interest" msgid "Interest"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:545 #: frontend/src/components/AppSidebar.vue:541
#: frontend/src/components/AppSidebar.vue:548 #: frontend/src/components/AppSidebar.vue:544
msgid "Introduction" msgid "Introduction"
msgstr "" msgstr ""
@@ -2624,7 +2675,7 @@ msgstr ""
msgid "Invite Request" msgid "Invite Request"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:481 #: frontend/src/components/AppSidebar.vue:477
msgid "Invite your team and students" msgid "Invite your team and students"
msgstr "" msgstr ""
@@ -2656,7 +2707,7 @@ msgstr ""
msgid "Issue Date" msgid "Issue Date"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:581 #: frontend/src/components/AppSidebar.vue:577
msgid "Issue a Certificate" msgid "Issue a Certificate"
msgstr "" msgstr ""
@@ -2957,6 +3008,7 @@ msgstr ""
#: lms/lms/doctype/lms_assignment/lms_assignment.json #: lms/lms/doctype/lms_assignment/lms_assignment.json
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json #: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json
#: lms/lms/doctype/lms_badge_assignment/lms_badge_assignment.json #: lms/lms/doctype/lms_badge_assignment/lms_badge_assignment.json
#: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/lms/doctype/lms_batch_enrollment/lms_batch_enrollment.json #: lms/lms/doctype/lms_batch_enrollment/lms_batch_enrollment.json
#: lms/lms/doctype/lms_batch_feedback/lms_batch_feedback.json #: lms/lms/doctype/lms_batch_feedback/lms_batch_feedback.json
#: lms/lms/doctype/lms_certificate/lms_certificate.json #: lms/lms/doctype/lms_certificate/lms_certificate.json
@@ -3116,9 +3168,9 @@ msgid "LiveCode URL"
msgstr "" msgstr ""
#: frontend/src/components/Members.vue:109 #: frontend/src/components/Members.vue:109
#: frontend/src/pages/Assignments.vue:69 frontend/src/pages/Batches.vue:82 #: frontend/src/pages/Assignments.vue:69 frontend/src/pages/Batches.vue:80
#: frontend/src/pages/CertifiedParticipants.vue:100 #: frontend/src/pages/CertifiedParticipants.vue:100
#: frontend/src/pages/Courses.vue:77 #: frontend/src/pages/Courses.vue:75
#: frontend/src/pages/QuizSubmissionList.vue:39 #: frontend/src/pages/QuizSubmissionList.vue:39
#: frontend/src/pages/Quizzes.vue:55 #: frontend/src/pages/Quizzes.vue:55
msgid "Load More" msgid "Load More"
@@ -3142,7 +3194,7 @@ msgid "Location Preference"
msgstr "" msgstr ""
#: frontend/src/components/NoPermission.vue:28 #: frontend/src/components/NoPermission.vue:28
#: frontend/src/components/QuizBlock.vue:9 frontend/src/pages/Batch.vue:188 #: frontend/src/components/QuizBlock.vue:9 frontend/src/pages/Batch.vue:193
#: frontend/src/pages/Lesson.vue:53 #: frontend/src/pages/Lesson.vue:53
msgid "Login" msgid "Login"
msgstr "" msgstr ""
@@ -3236,7 +3288,7 @@ msgid "Maximum 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:172 #: frontend/src/pages/BatchForm.vue:177
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
msgid "Medium" msgid "Medium"
msgstr "" msgstr ""
@@ -3418,7 +3470,7 @@ 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'
#. Label of the meta_image (Attach Image) field in DocType 'LMS Settings' #. Label of the meta_image (Attach Image) field in DocType 'LMS Settings'
#: frontend/src/pages/BatchForm.vue:185 #: frontend/src/pages/BatchForm.vue:190
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
#: lms/lms/doctype/lms_settings/lms_settings.json #: lms/lms/doctype/lms_settings/lms_settings.json
msgid "Meta Image" msgid "Meta Image"
@@ -3479,7 +3531,7 @@ msgstr ""
msgid "Monday" msgid "Monday"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:589 #: frontend/src/components/AppSidebar.vue:585
msgid "Monetization" msgid "Monetization"
msgstr "" msgstr ""
@@ -3500,8 +3552,13 @@ msgstr ""
msgid "My calendar" msgid "My calendar"
msgstr "" msgstr ""
#: frontend/src/components/Modals/EmailTemplateModal.vue:24
msgid "Name"
msgstr ""
#. Option for the 'Event' (Select) field in DocType 'LMS Badge' #. Option for the 'Event' (Select) field in DocType 'LMS Badge'
#: frontend/src/components/Categories.vue:12 #: frontend/src/components/Categories.vue:27
#: frontend/src/components/EmailTemplates.vue:17
#: frontend/src/components/Evaluators.vue:24 #: frontend/src/components/Evaluators.vue:24
#: frontend/src/components/Members.vue:24 frontend/src/pages/Assignments.vue:19 #: frontend/src/components/Members.vue:24 frontend/src/pages/Assignments.vue:19
#: frontend/src/pages/Batches.vue:17 frontend/src/pages/Courses.vue:17 #: frontend/src/pages/Batches.vue:17 frontend/src/pages/Courses.vue:17
@@ -3518,6 +3575,10 @@ msgstr ""
msgid "New Course" msgid "New Course"
msgstr "" msgstr ""
#: frontend/src/components/Modals/EmailTemplateModal.vue:7
msgid "New Email Template"
msgstr ""
#: frontend/src/pages/Jobs.vue:23 #: frontend/src/pages/Jobs.vue:23
msgid "New Job" msgid "New Job"
msgstr "" msgstr ""
@@ -3617,7 +3678,7 @@ msgstr ""
msgid "No courses under review" msgid "No courses under review"
msgstr "" msgstr ""
#: frontend/src/components/BatchFeedback.vue:101 #: frontend/src/components/BatchFeedback.vue:60
msgid "No feedback received yet." msgid "No feedback received yet."
msgstr "" msgstr ""
@@ -3673,7 +3734,7 @@ msgstr ""
msgid "Not Graded" msgid "Not Graded"
msgstr "" msgstr ""
#: frontend/src/components/NoPermission.vue:7 frontend/src/pages/Batch.vue:156 #: frontend/src/components/NoPermission.vue:7 frontend/src/pages/Batch.vue:161
msgid "Not Permitted" msgid "Not Permitted"
msgstr "" msgstr ""
@@ -3842,7 +3903,7 @@ 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:245 #: frontend/src/pages/BatchForm.vue:250
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
msgid "Paid Batch" msgid "Paid Batch"
msgstr "" msgstr ""
@@ -4084,7 +4145,7 @@ msgstr ""
msgid "Please login to access the quiz." msgid "Please login to access the quiz."
msgstr "" msgstr ""
#: frontend/src/components/NoPermission.vue:25 frontend/src/pages/Batch.vue:167 #: frontend/src/components/NoPermission.vue:25 frontend/src/pages/Batch.vue:172
msgid "Please login to access this page." msgid "Please login to access this page."
msgstr "" msgstr ""
@@ -4223,7 +4284,7 @@ msgid "Previous"
msgstr "" 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'
#: frontend/src/pages/BatchForm.vue:240 #: frontend/src/pages/BatchForm.vue:245
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
msgid "Pricing" msgid "Pricing"
msgstr "" msgstr ""
@@ -4460,7 +4521,7 @@ msgstr ""
msgid "Quiz will appear at the bottom of the lesson." msgid "Quiz will appear at the bottom of the lesson."
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:573 #: frontend/src/components/AppSidebar.vue:569
#: frontend/src/pages/QuizForm.vue:443 frontend/src/pages/Quizzes.vue:142 #: frontend/src/pages/QuizForm.vue:443 frontend/src/pages/Quizzes.vue:142
#: frontend/src/pages/Quizzes.vue:152 lms/www/lms.py:251 #: frontend/src/pages/Quizzes.vue:152 lms/www/lms.py:251
msgid "Quizzes" msgid "Quizzes"
@@ -4471,7 +4532,7 @@ msgstr ""
#. 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:121 #: frontend/src/components/CourseCardOverlay.vue:121
#: 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:18
#: 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/lms_course.json
#: lms/lms/doctype/lms_course_review/lms_course_review.json #: lms/lms/doctype/lms_course_review/lms_course_review.json
@@ -4540,7 +4601,7 @@ msgstr ""
msgid "Related Courses" msgid "Related Courses"
msgstr "" msgstr ""
#: frontend/src/pages/BatchForm.vue:221 frontend/src/pages/CourseForm.vue:127 #: frontend/src/pages/BatchForm.vue:226 frontend/src/pages/CourseForm.vue:127
msgid "Remove" msgid "Remove"
msgstr "" msgstr ""
@@ -4578,7 +4639,7 @@ msgstr ""
#. Label of the review (Small Text) field in DocType 'LMS Course Review' #. Label of the review (Small Text) field in DocType 'LMS Course Review'
#. Label of a Link in the LMS Workspace #. Label of a Link in the LMS Workspace
#: frontend/src/components/Modals/ReviewModal.vue:26 #: frontend/src/components/Modals/ReviewModal.vue:20
#: lms/lms/doctype/lms_course_review/lms_course_review.json #: lms/lms/doctype/lms_course_review/lms_course_review.json
#: lms/lms/workspace/lms/lms.json lms/templates/reviews.html:143 #: lms/lms/workspace/lms/lms.json lms/templates/reviews.html:143
msgid "Review" msgid "Review"
@@ -4613,7 +4674,7 @@ msgstr ""
msgid "Role updated successfully" msgid "Role updated successfully"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:601 #: frontend/src/components/AppSidebar.vue:597
msgid "Roles" msgid "Roles"
msgstr "" msgstr ""
@@ -4678,6 +4739,7 @@ msgstr ""
#: frontend/src/components/Assignment.vue:46 #: frontend/src/components/Assignment.vue:46
#: frontend/src/components/Controls/CodeEditor.vue:25 #: frontend/src/components/Controls/CodeEditor.vue:25
#: frontend/src/components/Modals/AssignmentForm.vue:59 #: frontend/src/components/Modals/AssignmentForm.vue:59
#: frontend/src/components/Modals/EmailTemplateModal.vue:12
#: frontend/src/components/Modals/Event.vue:101 #: frontend/src/components/Modals/Event.vue:101
#: frontend/src/components/Modals/Event.vue:129 #: frontend/src/components/Modals/Event.vue:129
#: frontend/src/pages/BatchForm.vue:8 frontend/src/pages/CourseForm.vue:17 #: frontend/src/pages/BatchForm.vue:8 frontend/src/pages/CourseForm.vue:17
@@ -4729,7 +4791,7 @@ msgstr ""
msgid "Search by Name" msgid "Search by Name"
msgstr "" msgstr ""
#: frontend/src/pages/Batches.vue:47 frontend/src/pages/Courses.vue:43 #: frontend/src/pages/Batches.vue:45 frontend/src/pages/Courses.vue:41
msgid "Search by Title" msgid "Search by Title"
msgstr "" msgstr ""
@@ -4796,15 +4858,15 @@ msgstr ""
msgid "Set your Password" msgid "Set your Password"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:549 #: frontend/src/components/AppSidebar.vue:545
msgid "Setting up" msgid "Setting up"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:594 #: frontend/src/components/AppSidebar.vue:590
msgid "Setting up payment gateway" msgid "Setting up payment gateway"
msgstr "" msgstr ""
#: frontend/src/components/AppSidebar.vue:599 #: frontend/src/components/AppSidebar.vue:595
#: frontend/src/components/Modals/Settings.vue:7 #: frontend/src/components/Modals/Settings.vue:7
#: frontend/src/pages/BatchForm.vue:46 frontend/src/pages/CourseForm.vue:143 #: frontend/src/pages/BatchForm.vue:46 frontend/src/pages/CourseForm.vue:143
#: frontend/src/pages/ProfileRoles.vue:4 frontend/src/pages/QuizForm.vue:79 #: frontend/src/pages/ProfileRoles.vue:4 frontend/src/pages/QuizForm.vue:79
@@ -5132,6 +5194,7 @@ msgid "Subgroup"
msgstr "" msgstr ""
#: frontend/src/components/Modals/AnnouncementModal.vue:20 #: frontend/src/components/Modals/AnnouncementModal.vue:20
#: frontend/src/components/Modals/EmailTemplateModal.vue:31
msgid "Subject" msgid "Subject"
msgstr "" msgstr ""
@@ -5156,7 +5219,6 @@ msgstr ""
msgid "Submission by" msgid "Submission by"
msgstr "" msgstr ""
#: frontend/src/components/BatchFeedback.vue:14
#: frontend/src/components/Modals/AssessmentModal.vue:9 #: frontend/src/components/Modals/AssessmentModal.vue:9
#: frontend/src/components/Modals/BatchCourseModal.vue:9 #: frontend/src/components/Modals/BatchCourseModal.vue:9
#: frontend/src/components/Modals/EvaluationModal.vue:9 #: frontend/src/components/Modals/EvaluationModal.vue:9
@@ -5168,6 +5230,10 @@ msgstr ""
msgid "Submit" msgid "Submit"
msgstr "" msgstr ""
#: frontend/src/components/BatchFeedback.vue:35
msgid "Submit Feedback"
msgstr ""
#: frontend/src/pages/PersonaForm.vue:43 #: frontend/src/pages/PersonaForm.vue:43
msgid "Submit and Continue" msgid "Submit and Continue"
msgstr "" msgstr ""
@@ -5305,8 +5371,8 @@ msgstr ""
msgid "Text" msgid "Text"
msgstr "" msgstr ""
#: frontend/src/components/BatchFeedback.vue:7 #: frontend/src/components/BatchFeedback.vue:6
msgid "Thank you for providing your feedback!" msgid "Thank you for providing your feedback."
msgstr "" msgstr ""
#: lms/templates/emails/lms_course_interest.html:17 #: lms/templates/emails/lms_course_interest.html:17
@@ -5584,6 +5650,10 @@ msgstr ""
msgid "Total Signups" msgid "Total Signups"
msgstr "" msgstr ""
#: frontend/src/components/Modals/FeedbackModal.vue:11
msgid "Training Feedback"
msgstr ""
#. Option for the 'Location Preference' (Select) field in DocType 'User' #. Option for the 'Location Preference' (Select) field in DocType 'User'
#: lms/fixtures/custom_field.json #: lms/fixtures/custom_field.json
msgid "Travel" msgid "Travel"
@@ -5662,7 +5732,7 @@ msgstr ""
msgid "Unlisted" msgid "Unlisted"
msgstr "" msgstr ""
#: frontend/src/pages/Batches.vue:288 #: frontend/src/pages/Batches.vue:284
msgid "Unpublished" msgid "Unpublished"
msgstr "" msgstr ""
@@ -5684,14 +5754,14 @@ msgstr ""
#. Option for the 'Status' (Select) field in DocType 'Cohort' #. Option for the 'Status' (Select) field in DocType 'Cohort'
#. Option for the 'Status' (Select) field in DocType 'LMS Certificate Request' #. Option for the 'Status' (Select) field in DocType 'LMS Certificate Request'
#. Label of the upcoming (Check) field in DocType 'LMS Course' #. Label of the upcoming (Check) field in DocType 'LMS Course'
#: frontend/src/pages/Batches.vue:286 frontend/src/pages/CourseForm.vue:162 #: frontend/src/pages/Batches.vue:282 frontend/src/pages/CourseForm.vue:162
#: frontend/src/pages/Courses.vue:312 lms/lms/doctype/cohort/cohort.json #: frontend/src/pages/Courses.vue:312 lms/lms/doctype/cohort/cohort.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_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
msgid "Upcoming" msgid "Upcoming"
msgstr "" msgstr ""
#: frontend/src/pages/Batch.vue:179 #: frontend/src/pages/Batch.vue:184
msgid "Upcoming Batches" msgid "Upcoming Batches"
msgstr "" msgstr ""
@@ -5700,7 +5770,7 @@ msgstr ""
msgid "Upcoming Evaluations" msgid "Upcoming Evaluations"
msgstr "" msgstr ""
#: frontend/src/components/BrandSettings.vue:23 #: frontend/src/components/BrandSettings.vue:24
#: frontend/src/components/PaymentSettings.vue:27 #: frontend/src/components/PaymentSettings.vue:27
#: frontend/src/components/SettingDetails.vue:23 #: frontend/src/components/SettingDetails.vue:23
msgid "Update" msgid "Update"
@@ -5710,7 +5780,7 @@ msgstr ""
msgid "Update Password" msgid "Update Password"
msgstr "" msgstr ""
#: frontend/src/pages/BatchForm.vue:202 frontend/src/pages/CourseForm.vue:108 #: frontend/src/pages/BatchForm.vue:207 frontend/src/pages/CourseForm.vue:108
msgid "Upload" msgid "Upload"
msgstr "" msgstr ""
@@ -5722,6 +5792,10 @@ msgstr ""
msgid "Uploading {0}%" msgid "Uploading {0}%"
msgstr "" msgstr ""
#: frontend/src/components/Modals/EmailTemplateModal.vue:38
msgid "Use HTML"
msgstr ""
#. Label of the user (Link) field in DocType 'LMS Job Application' #. Label of the user (Link) field in DocType 'LMS Job Application'
#. Label of the email (Link) field in DocType 'Cohort Staff' #. Label of the email (Link) field in DocType 'Cohort Staff'
#. Label of the user (Link) field in DocType 'LMS Course Interest' #. Label of the user (Link) field in DocType 'LMS Course Interest'
@@ -5807,6 +5881,10 @@ msgstr ""
msgid "View Certificate" msgid "View Certificate"
msgstr "" msgstr ""
#: frontend/src/components/BatchFeedback.vue:56
msgid "View all feedback"
msgstr ""
#. Label of the visibility (Select) field in DocType 'LMS Batch Old' #. Label of the visibility (Select) field in DocType 'LMS Batch Old'
#: lms/lms/doctype/lms_batch_old/lms_batch_old.json #: lms/lms/doctype/lms_batch_old/lms_batch_old.json
msgid "Visibility" msgid "Visibility"
@@ -5945,7 +6023,7 @@ msgstr ""
msgid "You are already enrolled for this course." msgid "You are already enrolled for this course."
msgstr "" msgstr ""
#: frontend/src/pages/Batch.vue:161 #: frontend/src/pages/Batch.vue:166
msgid "You are not a member of this batch. Please checkout our upcoming batches." msgid "You are not a member of this batch. Please checkout our upcoming batches."
msgstr "" msgstr ""
@@ -6095,6 +6173,10 @@ msgstr ""
msgid "Your class on {0} is today" msgid "Your class on {0} is today"
msgstr "" msgstr ""
#: frontend/src/components/Modals/EmailTemplateModal.vue:35
msgid "Your enrollment in {{ batch_name }} is confirmed"
msgstr ""
#: lms/lms/notification/certificate_request_reminder/certificate_request_reminder.html:3 #: lms/lms/notification/certificate_request_reminder/certificate_request_reminder.html:3
#: lms/templates/emails/certificate_request_notification.html:3 #: lms/templates/emails/certificate_request_notification.html:3
msgid "Your evaluation for the course {0} has been scheduled on {1} at {2} {3}." msgid "Your evaluation for the course {0} has been scheduled on {1} at {2} {3}."
@@ -6209,10 +6291,18 @@ msgstr ""
msgid "ratings" msgid "ratings"
msgstr "" msgstr ""
#: frontend/src/components/Categories.vue:19
msgid "saving..."
msgstr ""
#: lms/templates/reviews.html:43 #: lms/templates/reviews.html:43
msgid "stars" msgid "stars"
msgstr "" msgstr ""
#: frontend/src/components/BatchFeedback.vue:12
msgid "to view your feedback."
msgstr ""
#: frontend/src/components/StudentHeatmap.vue:10 #: frontend/src/components/StudentHeatmap.vue:10
msgid "weeks" msgid "weeks"
msgstr "" msgstr ""

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: frappe\n" "Project-Id-Version: frappe\n"
"Report-Msgid-Bugs-To: jannat@frappe.io\n" "Report-Msgid-Bugs-To: jannat@frappe.io\n"
"POT-Creation-Date: 2025-05-16 16:04+0000\n" "POT-Creation-Date: 2025-05-16 16:04+0000\n"
"PO-Revision-Date: 2025-05-19 16:03\n" "PO-Revision-Date: 2025-05-24 17:46\n"
"Last-Translator: jannat@frappe.io\n" "Last-Translator: jannat@frappe.io\n"
"Language-Team: Serbian (Latin)\n" "Language-Team: Serbian (Latin)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -251,7 +251,7 @@ msgstr ""
#: lms/templates/quiz/quiz.html:141 #: lms/templates/quiz/quiz.html:141
msgid "All Submissions" msgid "All Submissions"
msgstr "Svi podneti podaci" msgstr "Sve podneseno"
#: lms/lms/doctype/lms_quiz/lms_quiz.py:44 #: lms/lms/doctype/lms_quiz/lms_quiz.py:44
msgid "All questions should have the same marks if the limit is set." msgid "All questions should have the same marks if the limit is set."
@@ -502,7 +502,7 @@ msgstr ""
#: frontend/src/pages/ProfileEvaluator.vue:137 #: frontend/src/pages/ProfileEvaluator.vue:137
msgid "Authorize Google Calendar Access" msgid "Authorize Google Calendar Access"
msgstr "" msgstr "Odobri pristup Google Calendar-u"
#. Option for the 'Event' (Select) field in DocType 'LMS Badge' #. Option for the 'Event' (Select) field in DocType 'LMS Badge'
#: lms/lms/doctype/lms_badge/lms_badge.json #: lms/lms/doctype/lms_badge/lms_badge.json
@@ -687,7 +687,7 @@ msgstr ""
#: frontend/src/components/Modals/EditProfile.vue:75 #: frontend/src/components/Modals/EditProfile.vue:75
msgid "Bio" msgid "Bio"
msgstr "" msgstr "Biografija"
#. Label of the body (Markdown Editor) field in DocType 'Course Lesson' #. Label of the body (Markdown Editor) field in DocType 'Course Lesson'
#: lms/lms/doctype/course_lesson/course_lesson.json #: lms/lms/doctype/course_lesson/course_lesson.json
@@ -765,7 +765,7 @@ msgstr "Kategorija"
#: frontend/src/components/Categories.vue:23 #: frontend/src/components/Categories.vue:23
msgid "Category Name" msgid "Category Name"
msgstr "" msgstr "Naziv kategorije"
#. Label of the certificate (Link) field in DocType 'LMS Enrollment' #. Label of the certificate (Link) field in DocType 'LMS Enrollment'
#. Label of a shortcut in the LMS Workspace #. Label of a shortcut in the LMS Workspace
@@ -886,7 +886,7 @@ msgstr ""
#: frontend/src/components/Quiz.vue:205 lms/templates/quiz/quiz.html:120 #: frontend/src/components/Quiz.vue:205 lms/templates/quiz/quiz.html:120
msgid "Check" msgid "Check"
msgstr "" msgstr "Označi"
#: lms/templates/emails/mention_template.html:10 #: lms/templates/emails/mention_template.html:10
msgid "Check Discussion" msgid "Check Discussion"
@@ -955,12 +955,12 @@ msgstr ""
#. Label of the client_id (Data) field in DocType 'Zoom Settings' #. Label of the client_id (Data) field in DocType 'Zoom Settings'
#: lms/lms/doctype/zoom_settings/zoom_settings.json #: lms/lms/doctype/zoom_settings/zoom_settings.json
msgid "Client ID" msgid "Client ID"
msgstr "" msgstr "ID klijenta"
#. Label of the client_secret (Password) field in DocType 'Zoom Settings' #. Label of the client_secret (Password) field in DocType 'Zoom Settings'
#: lms/lms/doctype/zoom_settings/zoom_settings.json #: lms/lms/doctype/zoom_settings/zoom_settings.json
msgid "Client Secret" msgid "Client Secret"
msgstr "" msgstr "Tajna klijenta"
#: frontend/src/components/Categories.vue:12 #: frontend/src/components/Categories.vue:12
#: frontend/src/components/Evaluators.vue:24 #: frontend/src/components/Evaluators.vue:24
@@ -983,7 +983,7 @@ msgstr ""
#. Label of the code (Code) field in DocType 'LMS Exercise' #. Label of the code (Code) field in DocType 'LMS Exercise'
#: lms/lms/doctype/lms_exercise/lms_exercise.json #: lms/lms/doctype/lms_exercise/lms_exercise.json
msgid "Code" msgid "Code"
msgstr "" msgstr "Šifra"
#. Name of a DocType #. Name of a DocType
#. Label of the cohort (Link) field in DocType 'Cohort Join Request' #. Label of the cohort (Link) field in DocType 'Cohort Join Request'
@@ -1186,7 +1186,7 @@ msgstr ""
#. Label of the confirmation_email_template (Link) field in DocType 'LMS Batch' #. Label of the confirmation_email_template (Link) field in DocType 'LMS Batch'
#: lms/lms/doctype/lms_batch/lms_batch.json #: lms/lms/doctype/lms_batch/lms_batch.json
msgid "Confirmation Email Template" msgid "Confirmation Email Template"
msgstr "" msgstr "Šablon imejla za potvrdu"
#: lms/lms/doctype/lms_certificate/lms_certificate.py:29 #: lms/lms/doctype/lms_certificate/lms_certificate.py:29
msgid "Congratulations on getting certified!" msgid "Congratulations on getting certified!"
@@ -1744,7 +1744,7 @@ msgstr ""
#: lms/lms/doctype/lms_assignment/lms_assignment.json #: lms/lms/doctype/lms_assignment/lms_assignment.json
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json #: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json
msgid "Document" msgid "Document"
msgstr "" msgstr "Dokument"
#: lms/templates/emails/payment_reminder.html:11 #: lms/templates/emails/payment_reminder.html:11
msgid "Dont miss this opportunity to enhance your skills. Click below to complete your enrollment" msgid "Dont miss this opportunity to enhance your skills. Click below to complete your enrollment"
@@ -1794,7 +1794,7 @@ msgstr ""
#: frontend/src/pages/JobDetail.vue:34 frontend/src/pages/Lesson.vue:135 #: frontend/src/pages/JobDetail.vue:34 frontend/src/pages/Lesson.vue:135
#: frontend/src/pages/Profile.vue:36 frontend/src/pages/Programs.vue:53 #: frontend/src/pages/Profile.vue:36 frontend/src/pages/Programs.vue:53
msgid "Edit" msgid "Edit"
msgstr "Izmeni" msgstr "Uredi"
#: frontend/src/components/Modals/AssignmentForm.vue:14 #: frontend/src/components/Modals/AssignmentForm.vue:14
msgid "Edit Assignment" msgid "Edit Assignment"
@@ -1840,7 +1840,7 @@ msgstr ""
#. Label of the email_sent (Check) field in DocType 'LMS Course Interest' #. Label of the email_sent (Check) field in DocType 'LMS Course Interest'
#: lms/lms/doctype/lms_course_interest/lms_course_interest.json #: lms/lms/doctype/lms_course_interest/lms_course_interest.json
msgid "Email Sent" msgid "Email Sent"
msgstr "" msgstr "Imejl poslat"
#: frontend/src/pages/BatchForm.vue:154 #: frontend/src/pages/BatchForm.vue:154
msgid "Email Template" msgid "Email Template"
@@ -1864,7 +1864,7 @@ msgstr "Zaposleno lice"
#. Label of the enable (Check) field in DocType 'Zoom Settings' #. Label of the enable (Check) field in DocType 'Zoom Settings'
#: lms/lms/doctype/zoom_settings/zoom_settings.json #: lms/lms/doctype/zoom_settings/zoom_settings.json
msgid "Enable" msgid "Enable"
msgstr "" msgstr "Omogući"
#: lms/lms/doctype/lms_settings/lms_settings.py:21 #: lms/lms/doctype/lms_settings/lms_settings.py:21
msgid "Enable Google API in Google Settings to send calendar invites for evaluations." msgid "Enable Google API in Google Settings to send calendar invites for evaluations."
@@ -2149,7 +2149,7 @@ msgstr ""
#. Label of the field_to_check (Select) field in DocType 'LMS Badge' #. Label of the field_to_check (Select) field in DocType 'LMS Badge'
#: lms/lms/doctype/lms_badge/lms_badge.json #: lms/lms/doctype/lms_badge/lms_badge.json
msgid "Field To Check" msgid "Field To Check"
msgstr "" msgstr "Polje za proveru"
#. Label of the major (Data) field in DocType 'Education Detail' #. Label of the major (Data) field in DocType 'Education Detail'
#: lms/lms/doctype/education_detail/education_detail.json #: lms/lms/doctype/education_detail/education_detail.json
@@ -2293,7 +2293,7 @@ msgstr ""
#. Request' #. Request'
#: lms/lms/doctype/lms_certificate_request/lms_certificate_request.json #: lms/lms/doctype/lms_certificate_request/lms_certificate_request.json
msgid "Google Meet Link" msgid "Google Meet Link"
msgstr "" msgstr "Google Meet Link"
#. Label of the grade (Data) field in DocType 'Education Detail' #. Label of the grade (Data) field in DocType 'Education Detail'
#: frontend/src/components/Assignment.vue:158 #: frontend/src/components/Assignment.vue:158
@@ -2475,7 +2475,7 @@ msgstr ""
#: lms/lms/doctype/lms_badge/lms_badge.json #: lms/lms/doctype/lms_badge/lms_badge.json
#: lms/lms/doctype/lms_exercise/lms_exercise.json #: lms/lms/doctype/lms_exercise/lms_exercise.json
msgid "Image" msgid "Image"
msgstr "" msgstr "Slika"
#: frontend/src/components/Modals/EditCoverImage.vue:58 #: frontend/src/components/Modals/EditCoverImage.vue:58
#: frontend/src/components/UnsplashImageBrowser.vue:52 #: frontend/src/components/UnsplashImageBrowser.vue:52
@@ -3369,7 +3369,7 @@ msgstr ""
#. Group in LMS Batch Old's connections #. Group in LMS Batch Old's connections
#: lms/lms/doctype/lms_batch_old/lms_batch_old.json #: lms/lms/doctype/lms_batch_old/lms_batch_old.json
msgid "Members" msgid "Members"
msgstr "" msgstr "Članovi"
#. Label of the membership (Select) field in DocType 'LMS Batch Old' #. Label of the membership (Select) field in DocType 'LMS Batch Old'
#: lms/lms/doctype/lms_batch_old/lms_batch_old.json #: lms/lms/doctype/lms_batch_old/lms_batch_old.json
@@ -3659,7 +3659,7 @@ msgstr "Nije dozvoljeno"
#. Submission' #. Submission'
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json #: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json
msgid "Not Applicable" msgid "Not Applicable"
msgstr "Nije primenljivo" msgstr "Nije primenjivo"
#: lms/templates/assessments.html:48 #: lms/templates/assessments.html:48
msgid "Not Attempted" msgid "Not Attempted"
@@ -3707,7 +3707,7 @@ 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"
msgstr "" msgstr "OAuth ID klijenta"
#. Option for the 'Location Preference' (Select) field in DocType 'User' #. Option for the 'Location Preference' (Select) field in DocType 'User'
#: lms/fixtures/custom_field.json #: lms/fixtures/custom_field.json
@@ -3997,7 +3997,7 @@ msgstr "Na čekanju"
#: frontend/src/pages/QuizSubmissionList.vue:102 #: frontend/src/pages/QuizSubmissionList.vue:102
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json #: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json
msgid "Percentage" msgid "Percentage"
msgstr "" msgstr "Procenat"
#. Option for the 'Grade Type' (Select) field in DocType 'Education Detail' #. Option for the 'Grade Type' (Select) field in DocType 'Education Detail'
#: lms/lms/doctype/education_detail/education_detail.json #: lms/lms/doctype/education_detail/education_detail.json
@@ -4214,7 +4214,7 @@ msgstr ""
#. Label of the image (Attach Image) field in DocType 'LMS Course' #. Label of the image (Attach Image) field in DocType 'LMS Course'
#: lms/lms/doctype/lms_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
msgid "Preview Image" msgid "Preview Image"
msgstr "" msgstr "Pregled slike"
#: frontend/src/pages/CourseForm.vue:195 #: frontend/src/pages/CourseForm.vue:195
msgid "Preview Video" msgid "Preview Video"
@@ -4345,7 +4345,7 @@ msgstr ""
#: frontend/src/pages/CourseForm.vue:154 #: frontend/src/pages/CourseForm.vue:154
#: lms/lms/doctype/lms_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
msgid "Published On" msgid "Published On"
msgstr "" msgstr "Objavljeno na"
#. Label of the purchased_certificate (Check) field in DocType 'LMS Enrollment' #. Label of the purchased_certificate (Check) field in DocType 'LMS Enrollment'
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json #: lms/lms/doctype/lms_enrollment/lms_enrollment.json
@@ -4494,7 +4494,7 @@ msgstr ""
#. Timetable' #. Timetable'
#: lms/lms/doctype/lms_batch_timetable/lms_batch_timetable.json #: lms/lms/doctype/lms_batch_timetable/lms_batch_timetable.json
msgid "Reference DocName" msgid "Reference DocName"
msgstr "" msgstr "Naziv referentnog dokumenta"
#. Label of the reference_doctype (Link) field in DocType 'LMS Batch Timetable' #. Label of the reference_doctype (Link) field in DocType 'LMS Batch Timetable'
#. Label of the reference_doctype (Link) field in DocType 'LMS Timetable #. Label of the reference_doctype (Link) field in DocType 'LMS Timetable
@@ -4502,7 +4502,7 @@ msgstr ""
#: lms/lms/doctype/lms_batch_timetable/lms_batch_timetable.json #: lms/lms/doctype/lms_batch_timetable/lms_batch_timetable.json
#: lms/lms/doctype/lms_timetable_legend/lms_timetable_legend.json #: lms/lms/doctype/lms_timetable_legend/lms_timetable_legend.json
msgid "Reference DocType" msgid "Reference DocType"
msgstr "" msgstr "DocType referenca"
#. Label of the reference_doctype (Link) field in DocType 'LMS Badge' #. Label of the reference_doctype (Link) field in DocType 'LMS Badge'
#: lms/lms/doctype/lms_badge/lms_badge.json #: lms/lms/doctype/lms_badge/lms_badge.json
@@ -4597,7 +4597,7 @@ msgstr ""
#: lms/templates/reviews.html:4 #: lms/templates/reviews.html:4
msgid "Reviews" msgid "Reviews"
msgstr "" msgstr "Pregledi"
#. Label of the role (Select) field in DocType 'Cohort Staff' #. Label of the role (Select) field in DocType 'Cohort Staff'
#. Label of the role (Select) field in DocType 'LMS Enrollment' #. Label of the role (Select) field in DocType 'LMS Enrollment'
@@ -4707,7 +4707,7 @@ msgstr ""
#. Label of the scope (Select) field in DocType 'Cohort Web Page' #. Label of the scope (Select) field in DocType 'Cohort Web Page'
#: lms/lms/doctype/cohort_web_page/cohort_web_page.json #: lms/lms/doctype/cohort_web_page/cohort_web_page.json
msgid "Scope" msgid "Scope"
msgstr "" msgstr "Opseg"
#. Label of the score (Int) field in DocType 'LMS Quiz Submission' #. Label of the score (Int) field in DocType 'LMS Quiz Submission'
#: frontend/src/pages/QuizSubmission.vue:39 #: frontend/src/pages/QuizSubmission.vue:39
@@ -4878,12 +4878,12 @@ msgstr ""
#. Label of the sidebar_tab (Tab Break) field in DocType 'LMS Settings' #. Label of the sidebar_tab (Tab Break) field in DocType 'LMS Settings'
#: lms/lms/doctype/lms_settings/lms_settings.json #: lms/lms/doctype/lms_settings/lms_settings.json
msgid "Sidebar" msgid "Sidebar"
msgstr "" msgstr "Bočna traka"
#. Label of the sidebar_items (Table) field in DocType 'LMS Settings' #. Label of the sidebar_items (Table) field in DocType 'LMS Settings'
#: lms/lms/doctype/lms_settings/lms_settings.json #: lms/lms/doctype/lms_settings/lms_settings.json
msgid "Sidebar Items" msgid "Sidebar Items"
msgstr "" msgstr "Stavke bočne trake"
#: lms/lms/user.py:29 #: lms/lms/user.py:29
msgid "Sign Up is disabled" msgid "Sign Up is disabled"
@@ -5056,7 +5056,7 @@ msgstr "Stanje"
#: lms/lms/doctype/lms_course/lms_course.json #: lms/lms/doctype/lms_course/lms_course.json
#: lms/lms/doctype/lms_settings/lms_settings.json lms/www/lms.py:204 #: lms/lms/doctype/lms_settings/lms_settings.json lms/www/lms.py:204
msgid "Statistics" msgid "Statistics"
msgstr "" msgstr "Statistika"
#. Label of the status (Select) field in DocType 'Job Opportunity' #. Label of the status (Select) field in DocType 'Job Opportunity'
#. Label of the status (Select) field in DocType 'Cohort' #. Label of the status (Select) field in DocType 'Cohort'
@@ -5135,7 +5135,7 @@ msgstr ""
#: frontend/src/components/Modals/AnnouncementModal.vue:20 #: frontend/src/components/Modals/AnnouncementModal.vue:20
msgid "Subject" msgid "Subject"
msgstr "Predmet" msgstr "Naslov"
#: frontend/src/components/Modals/AnnouncementModal.vue:93 #: frontend/src/components/Modals/AnnouncementModal.vue:93
msgid "Subject is required" msgid "Subject is required"
@@ -5305,7 +5305,7 @@ msgstr ""
#: lms/lms/doctype/lms_assignment/lms_assignment.json #: lms/lms/doctype/lms_assignment/lms_assignment.json
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json #: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json
msgid "Text" msgid "Text"
msgstr "" msgstr "Tekst"
#: frontend/src/components/BatchFeedback.vue:7 #: frontend/src/components/BatchFeedback.vue:7
msgid "Thank you for providing your feedback!" msgid "Thank you for providing your feedback!"
@@ -5638,7 +5638,7 @@ msgstr ""
#: lms/lms/doctype/lms_assignment/lms_assignment.json #: lms/lms/doctype/lms_assignment/lms_assignment.json
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json #: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json
msgid "URL" msgid "URL"
msgstr "" msgstr "URL"
#. Label of the unavailability_section (Section Break) field in DocType 'Course #. Label of the unavailability_section (Section Break) field in DocType 'Course
#. Evaluator' #. Evaluator'
@@ -5741,12 +5741,12 @@ msgstr ""
#. Label of the user_field (Select) field in DocType 'LMS Badge' #. Label of the user_field (Select) field in DocType 'LMS Badge'
#: lms/lms/doctype/lms_badge/lms_badge.json #: lms/lms/doctype/lms_badge/lms_badge.json
msgid "User Field" msgid "User Field"
msgstr "" msgstr "Korisničko polje"
#. Label of the user_image (Attach Image) field in DocType 'Course Evaluator' #. Label of the user_image (Attach Image) field in DocType 'Course Evaluator'
#: lms/lms/doctype/course_evaluator/course_evaluator.json #: lms/lms/doctype/course_evaluator/course_evaluator.json
msgid "User Image" msgid "User Image"
msgstr "" msgstr "Slika korisnika"
#. Option for the 'Type' (Select) field in DocType 'LMS Question' #. Option for the 'Type' (Select) field in DocType 'LMS Question'
#. Option for the 'Type' (Select) field in DocType 'LMS Quiz Question' #. Option for the 'Type' (Select) field in DocType 'LMS Quiz Question'
@@ -5812,7 +5812,7 @@ msgstr ""
#. Label of the visibility (Select) field in DocType 'LMS Batch Old' #. Label of the visibility (Select) field in DocType 'LMS Batch Old'
#: lms/lms/doctype/lms_batch_old/lms_batch_old.json #: lms/lms/doctype/lms_batch_old/lms_batch_old.json
msgid "Visibility" msgid "Visibility"
msgstr "" msgstr "Vidljivost"
#: frontend/src/components/BatchOverlay.vue:69 #: frontend/src/components/BatchOverlay.vue:69
msgid "Visit Batch" msgid "Visit Batch"
@@ -6157,7 +6157,7 @@ msgstr ""
#: frontend/src/pages/CertifiedParticipants.vue:82 #: frontend/src/pages/CertifiedParticipants.vue:82
msgid "certificate" msgid "certificate"
msgstr "" msgstr "sertifikat"
#: frontend/src/pages/CertifiedParticipants.vue:81 #: frontend/src/pages/CertifiedParticipants.vue:81
msgid "certificates" msgid "certificates"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: frappe\n" "Project-Id-Version: frappe\n"
"Report-Msgid-Bugs-To: jannat@frappe.io\n" "Report-Msgid-Bugs-To: jannat@frappe.io\n"
"POT-Creation-Date: 2025-05-16 16:04+0000\n" "POT-Creation-Date: 2025-05-16 16:04+0000\n"
"PO-Revision-Date: 2025-05-19 16:03\n" "PO-Revision-Date: 2025-05-24 17:46\n"
"Last-Translator: jannat@frappe.io\n" "Last-Translator: jannat@frappe.io\n"
"Language-Team: Chinese Simplified\n" "Language-Team: Chinese Simplified\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -109,7 +109,7 @@ msgstr "激活"
#: frontend/src/pages/Statistics.vue:16 #: frontend/src/pages/Statistics.vue:16
msgid "Active Members" msgid "Active Members"
msgstr "" msgstr "活跃成员"
#: frontend/src/components/Assessments.vue:11 #: frontend/src/components/Assessments.vue:11
#: frontend/src/components/BatchCourses.vue:11 #: frontend/src/components/BatchCourses.vue:11
@@ -329,7 +329,7 @@ msgstr "公告发送成功"
#: frontend/src/components/Modals/AnnouncementModal.vue:96 #: frontend/src/components/Modals/AnnouncementModal.vue:96
msgid "Announcement is required" msgid "Announcement is required"
msgstr "" msgstr "必须填写公告内容。"
#. Label of the answer (Text Editor) field in DocType 'LMS Assignment' #. Label of the answer (Text Editor) field in DocType 'LMS Assignment'
#. Label of the answer (Text Editor) field in DocType 'LMS Assignment #. Label of the answer (Text Editor) field in DocType 'LMS Assignment
@@ -352,7 +352,7 @@ msgstr "在分享批次链接至网络平台时显示"
#: frontend/src/pages/BatchForm.vue:206 #: frontend/src/pages/BatchForm.vue:206
msgid "Appears when the batch URL is shared on socials" msgid "Appears when the batch URL is shared on socials"
msgstr "" msgstr "当班级URL在社交平台分享时显示"
#: frontend/src/pages/JobDetail.vue:51 #: frontend/src/pages/JobDetail.vue:51
msgid "Apply" msgid "Apply"
@@ -475,7 +475,7 @@ msgstr "学员{1}的课时{0}作业已存在。"
#: frontend/src/components/Assignment.vue:356 #: frontend/src/components/Assignment.vue:356
msgid "Assignment submitted successfully" msgid "Assignment submitted successfully"
msgstr "" msgstr "作业提交成功。"
#: frontend/src/components/Modals/AssignmentForm.vue:138 #: frontend/src/components/Modals/AssignmentForm.vue:138
msgid "Assignment updated successfully" msgid "Assignment updated successfully"
@@ -517,7 +517,7 @@ msgstr "自动录制"
#: frontend/src/pages/ProfileEvaluator.vue:224 #: frontend/src/pages/ProfileEvaluator.vue:224
msgid "Availability updated successfully" msgid "Availability updated successfully"
msgstr "" msgstr "可用性更新成功。"
#: frontend/src/components/CourseCard.vue:55 #: frontend/src/components/CourseCard.vue:55
#: frontend/src/pages/CourseDetail.vue:20 #: frontend/src/pages/CourseDetail.vue:20
@@ -640,7 +640,7 @@ msgstr "批次结束日期不可早于开始日期"
#: lms/lms/api.py:246 #: lms/lms/api.py:246
msgid "Batch has already started." msgid "Batch has already started."
msgstr "" msgstr "班级已开始。"
#: lms/lms/api.py:241 #: lms/lms/api.py:241
msgid "Batch is sold out." msgid "Batch is sold out."
@@ -648,7 +648,7 @@ msgstr "该批次已满额。"
#: lms/lms/doctype/lms_batch/lms_batch.py:46 #: lms/lms/doctype/lms_batch/lms_batch.py:46
msgid "Batch start time cannot be greater than or equal to end time." msgid "Batch start time cannot be greater than or equal to end time."
msgstr "" msgstr "班级开始时间不可大于或等于结束时间。"
#: lms/templates/emails/batch_start_reminder.html:10 #: lms/templates/emails/batch_start_reminder.html:10
msgid "Batch:" msgid "Batch:"
@@ -873,7 +873,7 @@ msgstr "章节添加成功"
#: frontend/src/components/CourseOutline.vue:290 #: frontend/src/components/CourseOutline.vue:290
msgid "Chapter deleted successfully" msgid "Chapter deleted successfully"
msgstr "" msgstr "章节删除成功。"
#: frontend/src/components/Modals/ChapterModal.vue:196 #: frontend/src/components/Modals/ChapterModal.vue:196
msgid "Chapter updated successfully" msgid "Chapter updated successfully"
@@ -894,7 +894,7 @@ msgstr "查看讨论"
#: frontend/src/components/Modals/AssignmentForm.vue:55 #: frontend/src/components/Modals/AssignmentForm.vue:55
msgid "Check Submissions" msgid "Check Submissions"
msgstr "" msgstr "查看提交记录"
#: lms/templates/certificates_section.html:24 #: lms/templates/certificates_section.html:24
msgid "Check out the {0} to know more about certification." msgid "Check out the {0} to know more about certification."
@@ -917,7 +917,7 @@ msgstr "选择所有适用答案"
#: frontend/src/components/Modals/Question.vue:19 #: frontend/src/components/Modals/Question.vue:19
msgid "Choose an existing question" msgid "Choose an existing question"
msgstr "" msgstr "选择现有题目"
#: frontend/src/components/Controls/IconPicker.vue:27 #: frontend/src/components/Controls/IconPicker.vue:27
msgid "Choose an icon" msgid "Choose an icon"
@@ -1068,7 +1068,7 @@ msgstr "评估人评语"
#. Settings' #. Settings'
#: lms/lms/doctype/lms_settings/lms_settings.json #: lms/lms/doctype/lms_settings/lms_settings.json
msgid "Common keywords that will be used for all pages" msgid "Common keywords that will be used for all pages"
msgstr "" msgstr "全站通用关键词"
#. Label of the company (Data) field in DocType 'LMS Job Application' #. Label of the company (Data) field in DocType 'LMS Job Application'
#. Label of the company (Data) field in DocType 'Work Experience' #. Label of the company (Data) field in DocType 'Work Experience'
@@ -1171,7 +1171,7 @@ msgstr "执行评估"
#: frontend/src/pages/BatchForm.vue:141 #: frontend/src/pages/BatchForm.vue:141
msgid "Configurations" msgid "Configurations"
msgstr "" msgstr "系统配置"
#: frontend/src/components/UserDropdown.vue:180 #: frontend/src/components/UserDropdown.vue:180
msgid "Confirm" msgid "Confirm"
@@ -1327,7 +1327,7 @@ msgstr "课程完成"
#: frontend/src/pages/Statistics.vue:31 #: frontend/src/pages/Statistics.vue:31
msgid "Course Completions" msgid "Course Completions"
msgstr "" msgstr "课程完成情况"
#. Name of a role #. Name of a role
#: frontend/src/pages/ProfileRoles.vue:26 #: frontend/src/pages/ProfileRoles.vue:26
@@ -1352,7 +1352,7 @@ msgstr "课程描述"
#: frontend/src/pages/Statistics.vue:22 #: frontend/src/pages/Statistics.vue:22
msgid "Course Enrollments" msgid "Course Enrollments"
msgstr "" msgstr "课程注册记录"
#. Name of a DocType #. Name of a DocType
#: lms/lms/doctype/course_evaluator/course_evaluator.json #: lms/lms/doctype/course_evaluator/course_evaluator.json
@@ -1419,7 +1419,7 @@ msgstr "课程已添加至项目"
#: frontend/src/pages/CourseForm.vue:468 #: frontend/src/pages/CourseForm.vue:468
msgid "Course created successfully" msgid "Course created successfully"
msgstr "" msgstr "课程创建成功。"
#: frontend/src/pages/CourseForm.vue:489 #: frontend/src/pages/CourseForm.vue:489
msgid "Course deleted successfully" msgid "Course deleted successfully"
@@ -1431,7 +1431,7 @@ msgstr "课程移动成功"
#: frontend/src/pages/CourseForm.vue:451 #: frontend/src/pages/CourseForm.vue:451
msgid "Course updated successfully" msgid "Course updated successfully"
msgstr "" msgstr "课程更新成功。"
#: lms/lms/doctype/lms_batch/lms_batch.py:54 #: lms/lms/doctype/lms_batch/lms_batch.py:54
#: lms/lms/doctype/lms_program/lms_program.py:19 #: lms/lms/doctype/lms_program/lms_program.py:19
@@ -2047,7 +2047,7 @@ msgstr "付费证书需指定评估人"
#: frontend/src/components/Modals/EvaluationModal.vue:151 #: frontend/src/components/Modals/EvaluationModal.vue:151
msgid "Evaluator is unavailable" msgid "Evaluator is unavailable"
msgstr "" msgstr "评估人不可用"
#. Label of the event (Select) field in DocType 'LMS Badge' #. Label of the event (Select) field in DocType 'LMS Badge'
#. Label of the event (Link) field in DocType 'LMS Live Class' #. Label of the event (Link) field in DocType 'LMS Live Class'
@@ -2352,7 +2352,7 @@ msgstr "帮助我们改进课程材料"
#: frontend/src/pages/PersonaForm.vue:16 #: frontend/src/pages/PersonaForm.vue:16
msgid "Help us understand your needs" msgid "Help us understand your needs"
msgstr "" msgstr "请说明您的需求"
#: lms/lms/notification/certificate_request_reminder/certificate_request_reminder.html:1 #: lms/lms/notification/certificate_request_reminder/certificate_request_reminder.html:1
#: lms/templates/emails/certificate_request_notification.html:1 #: lms/templates/emails/certificate_request_notification.html:1
@@ -2425,7 +2425,7 @@ msgstr "图标"
#. Label of the user_category (Check) field in DocType 'LMS Settings' #. Label of the user_category (Check) field in DocType 'LMS Settings'
#: lms/lms/doctype/lms_settings/lms_settings.json #: lms/lms/doctype/lms_settings/lms_settings.json
msgid "Identify User Category" msgid "Identify User Category"
msgstr "" msgstr "识别用户类别"
#: frontend/src/components/LessonHelp.vue:11 #: frontend/src/components/LessonHelp.vue:11
msgid "If Include in Preview is enabled for a lesson then the lesson will also be accessible to non logged in users." msgid "If Include in Preview is enabled for a lesson then the lesson will also be accessible to non logged in users."
@@ -3038,19 +3038,19 @@ msgstr "课时标题"
#: frontend/src/pages/LessonForm.vue:414 #: frontend/src/pages/LessonForm.vue:414
msgid "Lesson created successfully" msgid "Lesson created successfully"
msgstr "" msgstr "课时创建成功。"
#: frontend/src/components/CourseOutline.vue:217 #: frontend/src/components/CourseOutline.vue:217
msgid "Lesson deleted successfully" msgid "Lesson deleted successfully"
msgstr "" msgstr "课时删除成功。"
#: frontend/src/components/CourseOutline.vue:232 #: frontend/src/components/CourseOutline.vue:232
msgid "Lesson moved successfully" msgid "Lesson moved successfully"
msgstr "" msgstr "课时移动成功。"
#: frontend/src/pages/LessonForm.vue:438 #: frontend/src/pages/LessonForm.vue:438
msgid "Lesson updated successfully" msgid "Lesson updated successfully"
msgstr "" 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
@@ -3429,7 +3429,7 @@ msgstr "元图片"
#. Label of the meta_keywords (Small Text) field in DocType 'LMS Settings' #. Label of the meta_keywords (Small Text) field in DocType 'LMS Settings'
#: lms/lms/doctype/lms_settings/lms_settings.json #: lms/lms/doctype/lms_settings/lms_settings.json
msgid "Meta Keywords" msgid "Meta Keywords"
msgstr "" msgstr "元关键词"
#. Label of the milestone (Check) field in DocType 'LMS Batch Timetable' #. Label of the milestone (Check) field in DocType 'LMS Batch Timetable'
#: lms/lms/doctype/lms_batch_timetable/lms_batch_timetable.json #: lms/lms/doctype/lms_batch_timetable/lms_batch_timetable.json
@@ -3637,7 +3637,7 @@ msgstr "该日期无可用时段"
#: frontend/src/components/Modals/AnnouncementModal.vue:90 #: frontend/src/components/Modals/AnnouncementModal.vue:90
msgid "No students in this batch" msgid "No students in this batch"
msgstr "" msgstr "本班级暂无学员"
#: frontend/src/pages/AssignmentSubmissionList.vue:67 #: frontend/src/pages/AssignmentSubmissionList.vue:67
msgid "No submissions" msgid "No submissions"
@@ -4011,7 +4011,7 @@ msgstr "百分比/状态"
#. Label of the persona_captured (Check) field in DocType 'LMS Settings' #. Label of the persona_captured (Check) field in DocType 'LMS Settings'
#: lms/lms/doctype/lms_settings/lms_settings.json #: lms/lms/doctype/lms_settings/lms_settings.json
msgid "Persona Captured" msgid "Persona Captured"
msgstr "" msgstr "用户画像已采集"
#: frontend/src/pages/Billing.vue:99 #: frontend/src/pages/Billing.vue:99
msgid "Phone Number" msgid "Phone Number"
@@ -4125,7 +4125,7 @@ msgstr "请选择时区"
#: frontend/src/components/Quiz.vue:497 #: frontend/src/components/Quiz.vue:497
msgid "Please select an option" msgid "Please select an option"
msgstr "" msgstr "请选择选项"
#: lms/templates/emails/job_report.html:6 #: lms/templates/emails/job_report.html:6
msgid "Please take appropriate action at {0}" msgid "Please take appropriate action at {0}"
@@ -4146,7 +4146,7 @@ msgstr "分数点如70分"
#: frontend/src/components/Modals/Question.vue:62 #: frontend/src/components/Modals/Question.vue:62
msgid "Possibilities" msgid "Possibilities"
msgstr "" msgstr "可能性分析"
#: frontend/src/components/Modals/Question.vue:88 #: frontend/src/components/Modals/Question.vue:88
msgid "Possibility" msgid "Possibility"
@@ -4613,7 +4613,7 @@ msgstr "角色偏好"
#: frontend/src/pages/ProfileRoles.vue:105 #: frontend/src/pages/ProfileRoles.vue:105
msgid "Role updated successfully" msgid "Role updated successfully"
msgstr "" msgstr "角色更新成功。"
#: frontend/src/components/AppSidebar.vue:601 #: frontend/src/components/AppSidebar.vue:601
msgid "Roles" msgid "Roles"
@@ -4756,7 +4756,7 @@ msgstr "剩余席位"
#: lms/lms/doctype/lms_batch/lms_batch.py:103 #: lms/lms/doctype/lms_batch/lms_batch.py:103
msgid "Seat count cannot be negative." msgid "Seat count cannot be negative."
msgstr "" msgstr "座位数不可为负数。"
#: frontend/src/components/BatchCard.vue:15 #: frontend/src/components/BatchCard.vue:15
#: frontend/src/components/BatchOverlay.vue:14 #: frontend/src/components/BatchOverlay.vue:14
@@ -4939,11 +4939,11 @@ msgstr "部分日程时段存在重叠"
#: frontend/src/pages/ProfileEvaluator.vue:201 #: frontend/src/pages/ProfileEvaluator.vue:201
msgid "Slot added successfully" msgid "Slot added successfully"
msgstr "" msgstr "时段添加成功。"
#: frontend/src/pages/ProfileEvaluator.vue:240 #: frontend/src/pages/ProfileEvaluator.vue:240
msgid "Slot deleted successfully" msgid "Slot deleted successfully"
msgstr "" msgstr "时段删除成功。"
#. Label of the slug (Data) field in DocType 'Cohort' #. Label of the slug (Data) field in DocType 'Cohort'
#. Label of the slug (Data) field in DocType 'Cohort Subgroup' #. Label of the slug (Data) field in DocType 'Cohort Subgroup'
@@ -5139,7 +5139,7 @@ msgstr "主题"
#: frontend/src/components/Modals/AnnouncementModal.vue:93 #: frontend/src/components/Modals/AnnouncementModal.vue:93
msgid "Subject is required" msgid "Subject is required"
msgstr "" msgstr "必须填写主题"
#: frontend/src/components/Assignment.vue:32 #: frontend/src/components/Assignment.vue:32
msgid "Submission" msgid "Submission"
@@ -5172,7 +5172,7 @@ msgstr "提交"
#: frontend/src/pages/PersonaForm.vue:43 #: frontend/src/pages/PersonaForm.vue:43
msgid "Submit and Continue" msgid "Submit and Continue"
msgstr "" msgstr "提交并继续"
#: frontend/src/components/Modals/JobApplicationModal.vue:23 #: frontend/src/components/Modals/JobApplicationModal.vue:23
msgid "Submit your resume to proceed with your application for this position. Upon submission, it will be shared with the job poster." msgid "Submit your resume to proceed with your application for this position. Upon submission, it will be shared with the job poster."
@@ -5364,7 +5364,7 @@ msgstr "本作业暂无提交记录"
#: frontend/src/components/EmptyState.vue:11 #: frontend/src/components/EmptyState.vue:11
msgid "There are no {0} currently. Keep an eye out, fresh learning experiences are on the way!" msgid "There are no {0} currently. Keep an eye out, fresh learning experiences are on the way!"
msgstr "" msgstr "当前暂无{0},新学习资源即将上线,敬请关注!"
#: lms/templates/course_list.html:14 #: lms/templates/course_list.html:14
msgid "There are no {0} on this site." msgid "There are no {0} on this site."
@@ -5415,11 +5415,11 @@ msgstr "本描述将展示在无元描述的列表及页面中"
#. Settings' #. Settings'
#: lms/lms/doctype/lms_settings/lms_settings.json #: lms/lms/doctype/lms_settings/lms_settings.json
msgid "This image will be shown on lists and pages that don't have an image by default" msgid "This image will be shown on lists and pages that don't have an image by default"
msgstr "" msgstr "本图片将显示在无默认图片的列表及页面"
#: frontend/src/pages/Lesson.vue:24 #: frontend/src/pages/Lesson.vue:24
msgid "This lesson is locked" msgid "This lesson is locked"
msgstr "" msgstr "本课时已锁定"
#: frontend/src/pages/Lesson.vue:29 #: frontend/src/pages/Lesson.vue:29
msgid "This lesson is not available for preview. Please enroll in the course to access it." msgid "This lesson is not available for preview. Please enroll in the course to access it."
@@ -5436,7 +5436,7 @@ msgstr "本测验共包含{0}道试题"
#: frontend/src/components/AppSidebar.vue:75 #: frontend/src/components/AppSidebar.vue:75
#: frontend/src/components/AppSidebar.vue:115 #: frontend/src/components/AppSidebar.vue:115
msgid "This site is being updated. You will not be able to make any changes. Full access will be restored shortly." msgid "This site is being updated. You will not be able to make any changes. Full access will be restored shortly."
msgstr "" msgstr "系统正在更新中,期间不可进行任何修改操作。完整访问权限将很快恢复。"
#. Option for the 'Day' (Select) field in DocType 'Evaluator Schedule' #. Option for the 'Day' (Select) field in DocType 'Evaluator Schedule'
#. Option for the 'Day' (Select) field in DocType 'LMS Certificate Request' #. Option for the 'Day' (Select) field in DocType 'LMS Certificate Request'
@@ -5648,7 +5648,7 @@ msgstr "不可用状态"
#: frontend/src/pages/ProfileEvaluator.vue:259 #: frontend/src/pages/ProfileEvaluator.vue:259
msgid "Unavailability updated successfully" msgid "Unavailability updated successfully"
msgstr "" msgstr "不可用状态更新成功"
#: lms/lms/doctype/course_evaluator/course_evaluator.py:29 #: lms/lms/doctype/course_evaluator/course_evaluator.py:29
msgid "Unavailable From Date cannot be greater than Unavailable To Date" msgid "Unavailable From Date cannot be greater than Unavailable To Date"
@@ -5856,7 +5856,7 @@ msgstr "网页"
#: frontend/src/components/Modals/PageModal.vue:80 #: frontend/src/components/Modals/PageModal.vue:80
msgid "Web page added to sidebar" msgid "Web page added to sidebar"
msgstr "" msgstr "网页已添加至侧边栏"
#. Option for the 'Day' (Select) field in DocType 'Evaluator Schedule' #. Option for the 'Day' (Select) field in DocType 'Evaluator Schedule'
#. Option for the 'Day' (Select) field in DocType 'LMS Certificate Request' #. Option for the 'Day' (Select) field in DocType 'LMS Certificate Request'
@@ -5872,7 +5872,7 @@ msgstr "欢迎使用{0}"
#: frontend/src/pages/PersonaForm.vue:32 #: frontend/src/pages/PersonaForm.vue:32
msgid "What best describes your role?" msgid "What best describes your role?"
msgstr "" msgstr "请选择最能描述您角色的选项"
#: frontend/src/components/LessonHelp.vue:6 #: frontend/src/components/LessonHelp.vue:6
msgid "What does include in preview mean?" msgid "What does include in preview mean?"
@@ -5880,7 +5880,7 @@ msgstr "「包含在预览中」的含义是什么?"
#: frontend/src/pages/PersonaForm.vue:21 #: frontend/src/pages/PersonaForm.vue:21
msgid "What is your use case for Frappe Learning?" msgid "What is your use case for Frappe Learning?"
msgstr "" msgstr "您使用Frappe Learning的主要场景是"
#: 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."
@@ -5978,11 +5978,11 @@ msgstr "简历已作为附件发送至本邮箱"
#: frontend/src/pages/ProfileEvaluator.vue:14 #: frontend/src/pages/ProfileEvaluator.vue:14
msgid "You cannot change the availability when the site is being updated." msgid "You cannot change the availability when the site is being updated."
msgstr "" msgstr "系统更新期间不可修改可用性设置。"
#: frontend/src/pages/ProfileRoles.vue:12 #: frontend/src/pages/ProfileRoles.vue:12
msgid "You cannot change the roles in read-only mode." msgid "You cannot change the roles in read-only mode."
msgstr "" msgstr "只读模式下不可修改角色。"
#: lms/lms/doctype/lms_certificate_request/lms_certificate_request.py:116 #: lms/lms/doctype/lms_certificate_request/lms_certificate_request.py:116
msgid "You cannot schedule evaluations after {0}." msgid "You cannot schedule evaluations after {0}."
@@ -6031,7 +6031,7 @@ msgstr "您已评价过本课程"
#: frontend/src/pages/JobDetail.vue:57 #: frontend/src/pages/JobDetail.vue:57
msgid "You have applied" msgid "You have applied"
msgstr "" msgstr "您已申请"
#: frontend/src/components/BatchOverlay.vue:159 #: frontend/src/components/BatchOverlay.vue:159
msgid "You have been enrolled in this batch" msgid "You have been enrolled in this batch"
@@ -6124,7 +6124,7 @@ msgstr "提交内容已保存,讲师将尽快评阅并通知最终结果"
#: frontend/src/pages/Lesson.vue:8 #: frontend/src/pages/Lesson.vue:8
msgid "Zen Mode" msgid "Zen Mode"
msgstr "" msgstr "禅模式"
#. Name of a DocType #. Name of a DocType
#: lms/lms/doctype/zoom_settings/zoom_settings.json #: lms/lms/doctype/zoom_settings/zoom_settings.json
@@ -6141,11 +6141,11 @@ msgstr "活动"
#: frontend/src/components/JobCard.vue:26 frontend/src/pages/JobDetail.vue:108 #: frontend/src/components/JobCard.vue:26 frontend/src/pages/JobDetail.vue:108
msgid "applicant" msgid "applicant"
msgstr "" msgstr "申请人"
#: frontend/src/components/JobCard.vue:26 frontend/src/pages/JobDetail.vue:108 #: frontend/src/components/JobCard.vue:26 frontend/src/pages/JobDetail.vue:108
msgid "applicants" msgid "applicants"
msgstr "" msgstr "申请人列表"
#: lms/templates/emails/payment_reminder.html:4 #: lms/templates/emails/payment_reminder.html:4
msgid "but didnt complete your payment" msgid "but didnt complete your payment"
@@ -6225,15 +6225,15 @@ msgstr "您可以"
#: frontend/src/pages/Assignments.vue:29 #: frontend/src/pages/Assignments.vue:29
msgid "{0} Assignments" msgid "{0} Assignments"
msgstr "" msgstr "{0}项作业"
#: frontend/src/pages/Jobs.vue:33 #: frontend/src/pages/Jobs.vue:33
msgid "{0} Open Jobs" msgid "{0} Open Jobs"
msgstr "" msgstr "{0}个开放职位"
#: frontend/src/pages/Quizzes.vue:25 #: frontend/src/pages/Quizzes.vue:25
msgid "{0} Quizzes" msgid "{0} Quizzes"
msgstr "" msgstr "{0}项测验"
#: lms/lms/api.py:853 lms/lms/api.py:861 #: lms/lms/api.py:853 lms/lms/api.py:861
msgid "{0} Settings not found" msgid "{0} Settings not found"

View File

@@ -26,7 +26,8 @@
"homepage": "https://github.com/frappe/lms#readme", "homepage": "https://github.com/frappe/lms#readme",
"devDependencies": { "devDependencies": {
"cypress": "^13.9.0", "cypress": "^13.9.0",
"cypress-file-upload": "^5.0.8" "cypress-file-upload": "^5.0.8",
"cypress-real-events": "^1.14.0"
}, },
"dependencies": { "dependencies": {
"pre-commit": "^1.2.2" "pre-commit": "^1.2.2"

View File

@@ -2107,6 +2107,11 @@ cypress-file-upload@^5.0.8:
resolved "https://registry.yarnpkg.com/cypress-file-upload/-/cypress-file-upload-5.0.8.tgz#d8824cbeaab798e44be8009769f9a6c9daa1b4a1" resolved "https://registry.yarnpkg.com/cypress-file-upload/-/cypress-file-upload-5.0.8.tgz#d8824cbeaab798e44be8009769f9a6c9daa1b4a1"
integrity sha512-+8VzNabRk3zG6x8f8BWArF/xA/W0VK4IZNx3MV0jFWrJS/qKn8eHfa5nU73P9fOQAgwHFJx7zjg4lwOnljMO8g== integrity sha512-+8VzNabRk3zG6x8f8BWArF/xA/W0VK4IZNx3MV0jFWrJS/qKn8eHfa5nU73P9fOQAgwHFJx7zjg4lwOnljMO8g==
cypress-real-events@^1.14.0:
version "1.14.0"
resolved "https://registry.yarnpkg.com/cypress-real-events/-/cypress-real-events-1.14.0.tgz#c5495db50a2bd247f4accde983af7153566945d3"
integrity sha512-XmI8y3OZLh6cjRroPalzzS++iv+pGCaD9G9kfIbtspgv7GVsDt30dkZvSXfgZb4rAN+3pOkMVB7e0j4oXydW7Q==
cypress@^13.9.0: cypress@^13.9.0:
version "13.17.0" version "13.17.0"
resolved "https://registry.yarnpkg.com/cypress/-/cypress-13.17.0.tgz#34c3d68080c4497eace0f353bd1629587a5f600d" resolved "https://registry.yarnpkg.com/cypress/-/cypress-13.17.0.tgz#34c3d68080c4497eace0f353bd1629587a5f600d"