fix: course count on batch dashboard
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
describe("Course Creation", () => {
|
||||
it("creates a new course", () => {
|
||||
cy.login();
|
||||
cy.wait(1000);
|
||||
cy.wait(500);
|
||||
cy.visit("/lms/courses");
|
||||
|
||||
// Close onboarding modal
|
||||
cy.closeOnboardingModal();
|
||||
|
||||
// Create a course
|
||||
cy.get("button").contains("New").click();
|
||||
cy.wait(1000);
|
||||
cy.wait(500);
|
||||
cy.url().should("include", "/courses/new/edit");
|
||||
|
||||
cy.get("label").contains("Title").type("Test Course");
|
||||
@@ -96,7 +99,8 @@ describe("Course Creation", () => {
|
||||
// View Course
|
||||
cy.wait(1000);
|
||||
cy.visit("/lms");
|
||||
cy.wait(500);
|
||||
cy.closeOnboardingModal();
|
||||
|
||||
cy.url().should("include", "/lms/courses");
|
||||
cy.get(".grid a:first").within(() => {
|
||||
cy.get("div").contains("Test Course");
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||
|
||||
import "cypress-file-upload";
|
||||
import "cypress-real-events";
|
||||
|
||||
Cypress.Commands.add("login", (email, password) => {
|
||||
if (!email) {
|
||||
@@ -68,3 +69,11 @@ Cypress.Commands.add("paste", { prevSubject: true }, (subject, text) => {
|
||||
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);
|
||||
});
|
||||
|
||||
3
frontend/components.d.ts
vendored
3
frontend/components.d.ts
vendored
@@ -47,11 +47,14 @@ declare module 'vue' {
|
||||
Discussions: typeof import('./src/components/Discussions.vue')['default']
|
||||
EditCoverImage: typeof import('./src/components/Modals/EditCoverImage.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']
|
||||
EvaluationModal: typeof import('./src/components/Modals/EvaluationModal.vue')['default']
|
||||
Evaluators: typeof import('./src/components/Evaluators.vue')['default']
|
||||
Event: typeof import('./src/components/Modals/Event.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']
|
||||
IconPicker: typeof import('./src/components/Controls/IconPicker.vue')['default']
|
||||
IndicatorIcon: typeof import('./src/components/Icons/IndicatorIcon.vue')['default']
|
||||
|
||||
@@ -39,9 +39,9 @@ const Layout = computed(() => {
|
||||
}
|
||||
if (screenSize.width < 640) {
|
||||
return MobileLayout
|
||||
} else {
|
||||
return DesktopLayout
|
||||
}
|
||||
|
||||
return DesktopLayout
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
|
||||
@@ -181,7 +181,6 @@
|
||||
import UserDropdown from '@/components/UserDropdown.vue'
|
||||
import CollapseSidebar from '@/components/Icons/CollapseSidebar.vue'
|
||||
import SidebarLink from '@/components/SidebarLink.vue'
|
||||
import { useStorage } from '@vueuse/core'
|
||||
import { ref, onMounted, inject, watch, reactive, markRaw, h } from 'vue'
|
||||
import { getSidebarLinks } from '../utils'
|
||||
import { usersStore } from '@/stores/user'
|
||||
@@ -244,6 +243,7 @@ const iconProps = {
|
||||
onMounted(() => {
|
||||
addNotifications()
|
||||
setSidebarLinks()
|
||||
setUpOnboarding()
|
||||
socket.on('publish_lms_notifications', (data) => {
|
||||
unreadNotifications.reload()
|
||||
})
|
||||
@@ -388,10 +388,6 @@ const deletePage = (link) => {
|
||||
)
|
||||
}
|
||||
|
||||
const getSidebarFromStorage = () => {
|
||||
return useStorage('sidebar_is_collapsed', false)
|
||||
}
|
||||
|
||||
const toggleSidebar = () => {
|
||||
sidebarStore.isSidebarCollapsed = !sidebarStore.isSidebarCollapsed
|
||||
localStorage.setItem(
|
||||
@@ -438,6 +434,7 @@ const steps = reactive([
|
||||
title: __('Add your first chapter'),
|
||||
icon: markRaw(h(FolderTree, iconProps)),
|
||||
completed: false,
|
||||
dependsOn: 'create_first_course',
|
||||
onClick: async () => {
|
||||
minimize.value = true
|
||||
let course = await getFirstCourse()
|
||||
@@ -453,6 +450,7 @@ const steps = reactive([
|
||||
title: __('Add your first lesson'),
|
||||
icon: markRaw(h(FileText, iconProps)),
|
||||
completed: false,
|
||||
dependsOn: 'create_first_chapter',
|
||||
onClick: async () => {
|
||||
minimize.value = true
|
||||
let course = await getFirstCourse()
|
||||
@@ -471,6 +469,7 @@ const steps = reactive([
|
||||
title: __('Create your first quiz'),
|
||||
icon: markRaw(h(CircleHelp, iconProps)),
|
||||
completed: false,
|
||||
dependsOn: 'create_first_course',
|
||||
onClick: () => {
|
||||
minimize.value = true
|
||||
router.push({ name: 'Quizzes' })
|
||||
@@ -502,6 +501,7 @@ const steps = reactive([
|
||||
title: __('Add students to your batch'),
|
||||
icon: markRaw(h(UserPlus, iconProps)),
|
||||
completed: false,
|
||||
dependsOn: 'create_first_batch',
|
||||
onClick: async () => {
|
||||
minimize.value = true
|
||||
let batch = await getFirstBatch()
|
||||
@@ -522,6 +522,7 @@ const steps = reactive([
|
||||
title: __('Add courses to your batch'),
|
||||
icon: markRaw(h(BookText, iconProps)),
|
||||
completed: false,
|
||||
dependsOn: 'create_first_batch',
|
||||
onClick: async () => {
|
||||
minimize.value = true
|
||||
let batch = await getFirstBatch()
|
||||
|
||||
@@ -1,44 +1,49 @@
|
||||
<template>
|
||||
<div v-if="user.data?.is_student">
|
||||
<div
|
||||
v-if="feedbackList.data?.length"
|
||||
class="bg-surface-blue-2 text-blue-700 p-2 rounded-md mb-5"
|
||||
>
|
||||
{{ __('Thank you for providing your feedback!') }}
|
||||
</div>
|
||||
<div v-else class="flex justify-between items-center mb-5">
|
||||
<div class="text-lg font-semibold">
|
||||
{{ __('Help Us Improve') }}
|
||||
<div>
|
||||
<div class="leading-5 mb-4">
|
||||
<div v-if="readOnly">
|
||||
{{ __('Thank you for providing your feedback.') }}
|
||||
<span
|
||||
@click="showFeedbackForm = !showFeedbackForm"
|
||||
class="underline cursor-pointer"
|
||||
>{{ __('Click here') }}</span
|
||||
>
|
||||
{{ __('to view your feedback.') }}
|
||||
</div>
|
||||
<div v-else>
|
||||
{{ __('Help us improve by providing your feedback.') }}
|
||||
</div>
|
||||
</div>
|
||||
<Button @click="submitFeedback()">
|
||||
{{ __('Submit') }}
|
||||
</Button>
|
||||
</div>
|
||||
<div class="space-y-8">
|
||||
<div class="flex items-center justify-between">
|
||||
<Rating
|
||||
v-for="key in ratingKeys"
|
||||
v-model="feedback[key]"
|
||||
:label="__(convertToTitleCase(key))"
|
||||
<div class="space-y-4" :class="showFeedbackForm ? 'block' : 'hidden'">
|
||||
<div class="space-y-4">
|
||||
<Rating
|
||||
v-for="key in ratingKeys"
|
||||
v-model="feedback[key]"
|
||||
:label="__(convertToTitleCase(key))"
|
||||
:readonly="readOnly"
|
||||
/>
|
||||
</div>
|
||||
<FormControl
|
||||
v-model="feedback.feedback"
|
||||
type="textarea"
|
||||
:label="__('Feedback')"
|
||||
:rows="9"
|
||||
:readonly="readOnly"
|
||||
/>
|
||||
<Button v-if="!readOnly" @click="submitFeedback">
|
||||
{{ __('Submit Feedback') }}
|
||||
</Button>
|
||||
</div>
|
||||
<FormControl
|
||||
v-model="feedback.feedback"
|
||||
type="textarea"
|
||||
:label="__('Feedback')"
|
||||
:rows="7"
|
||||
:readonly="readOnly"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="feedbackList.data?.length">
|
||||
<div class="text-lg font-semibold mb-5">
|
||||
{{ __('Average of Feedback Received') }}
|
||||
<div class="leading-5 text-sm mb-2 mt-5">
|
||||
{{ __('Average Feedback Received') }}
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between mb-10">
|
||||
<div class="space-y-4">
|
||||
<Rating
|
||||
v-for="key in ratingKeys"
|
||||
v-model="average[key]"
|
||||
@@ -47,81 +52,32 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="text-lg font-semibold mb-5">
|
||||
{{ __('All Feedback') }}
|
||||
</div>
|
||||
<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>
|
||||
<Button variant="outline" class="mt-5" @click="showAllFeedback = true">
|
||||
{{ __('View all feedback') }}
|
||||
</Button>
|
||||
</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.') }}
|
||||
</div>
|
||||
<FeedbackModal
|
||||
v-if="feedbackList.data?.length"
|
||||
v-model="showAllFeedback"
|
||||
:feedbackList="feedbackList.data"
|
||||
/>
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed, inject, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { inject, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { convertToTitleCase } from '@/utils'
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
createListResource,
|
||||
FormControl,
|
||||
ListView,
|
||||
ListHeader,
|
||||
ListRows,
|
||||
ListRow,
|
||||
ListRowItem,
|
||||
Rating,
|
||||
} from 'frappe-ui'
|
||||
import { Button, createListResource, FormControl, Rating } from 'frappe-ui'
|
||||
import FeedbackModal from '@/components/Modals/FeedbackModal.vue'
|
||||
|
||||
const user = inject('$user')
|
||||
const ratingKeys = ['content', 'instructors', 'value']
|
||||
const readOnly = ref(false)
|
||||
const average = reactive({})
|
||||
const feedback = reactive({})
|
||||
const showFeedbackForm = ref(true)
|
||||
const showAllFeedback = ref(false)
|
||||
|
||||
const props = defineProps({
|
||||
batch: {
|
||||
@@ -167,6 +123,7 @@ watch(
|
||||
if (feedbackList.data.length) {
|
||||
let data = feedbackList.data
|
||||
readOnly.value = true
|
||||
showFeedbackForm.value = false
|
||||
|
||||
ratingKeys.forEach((key) => {
|
||||
average[key] = 0
|
||||
@@ -201,40 +158,11 @@ const submitFeedback = () => {
|
||||
{
|
||||
onSuccess: () => {
|
||||
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>
|
||||
<style>
|
||||
.feedback-list > button > div {
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
</div>
|
||||
<div class="overflow-y-auto">
|
||||
<SettingFields :fields="fields" :data="data.data" />
|
||||
<div class="flex flex-row-reverse mt-auto">
|
||||
<Button variant="solid" :loading="saveSettings.loading" @click="update">
|
||||
{{ __('Update') }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-row-reverse mt-auto">
|
||||
<Button variant="solid" :loading="saveSettings.loading" @click="update">
|
||||
{{ __('Update') }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
<template>
|
||||
<div class="flex flex-col min-h-0">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-xl font-semibold mb-5 text-ink-gray-9">
|
||||
{{ label }}
|
||||
<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">
|
||||
<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>
|
||||
<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
|
||||
@@ -29,13 +45,39 @@
|
||||
</div>
|
||||
|
||||
<div class="overflow-y-scroll">
|
||||
<div class="text-base space-y-2">
|
||||
<FormControl
|
||||
:value="cat.category"
|
||||
type="text"
|
||||
v-for="cat in categories.data"
|
||||
@change.stop="(e) => update(cat.name, e.target.value)"
|
||||
/>
|
||||
<div class="divide-y space-y-2">
|
||||
<div
|
||||
v-for="(cat, index) in categories.data"
|
||||
:key="cat.name"
|
||||
class="pt-2"
|
||||
>
|
||||
<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>
|
||||
@@ -44,16 +86,22 @@
|
||||
import {
|
||||
Button,
|
||||
FormControl,
|
||||
LoadingIndicator,
|
||||
createListResource,
|
||||
createResource,
|
||||
debounce,
|
||||
toast,
|
||||
} from 'frappe-ui'
|
||||
import { Plus, X } from 'lucide-vue-next'
|
||||
import { Plus, Trash2, X } from 'lucide-vue-next'
|
||||
import { ref } from 'vue'
|
||||
import { cleanError } from '@/utils'
|
||||
|
||||
const showForm = ref(false)
|
||||
const category = ref(null)
|
||||
const categoryInput = ref(null)
|
||||
const saving = ref(false)
|
||||
const editing = ref(null)
|
||||
const editedValue = ref('')
|
||||
const editInputRef = ref([])
|
||||
|
||||
const props = defineProps({
|
||||
label: {
|
||||
@@ -72,25 +120,20 @@ const categories = createListResource({
|
||||
auto: true,
|
||||
})
|
||||
|
||||
const newCategory = createResource({
|
||||
url: 'frappe.client.insert',
|
||||
makeParams(values) {
|
||||
return {
|
||||
doc: {
|
||||
doctype: 'LMS Category',
|
||||
category: category.value,
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const addCategory = () => {
|
||||
newCategory.submit(
|
||||
{},
|
||||
categories.insert.submit(
|
||||
{
|
||||
category: category.value,
|
||||
},
|
||||
{
|
||||
onSuccess(data) {
|
||||
categories.reload()
|
||||
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) => {
|
||||
saving.value = true
|
||||
updateCategory.submit(
|
||||
{
|
||||
name: name,
|
||||
@@ -122,9 +166,51 @@ const update = (name, value) => {
|
||||
},
|
||||
{
|
||||
onSuccess() {
|
||||
saving.value = false
|
||||
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>
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
v-if="parseInt(course.data.rating) > 0"
|
||||
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">
|
||||
{{ course.data.rating }} {{ __('Rating') }}
|
||||
</span>
|
||||
|
||||
@@ -35,14 +35,14 @@
|
||||
<span class="text-ink-gray-7">
|
||||
{{ review.creation }}
|
||||
</span>
|
||||
<div class="flex mt-2">
|
||||
<div class="flex mt-2 space-x-1">
|
||||
<Star
|
||||
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="
|
||||
index <= Math.ceil(review.rating)
|
||||
? 'fill-orange-500'
|
||||
: 'fill-gray-600'
|
||||
? 'fill-yellow-500'
|
||||
: 'fill-gray-300'
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
||||
160
frontend/src/components/EmailTemplates.vue
Normal file
160
frontend/src/components/EmailTemplates.vue
Normal 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>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex min-h-0 flex-col text-base">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div>
|
||||
<div class="text-xl font-semibold mb-1 text-ink-gray-9">
|
||||
@@ -39,25 +39,27 @@
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div class="divide-y">
|
||||
<div
|
||||
v-for="evaluator in evaluators.data"
|
||||
@click="openProfile(evaluator.username)"
|
||||
class="cursor-pointer"
|
||||
>
|
||||
<div class="flex items-center justify-between py-3">
|
||||
<div class="flex items-center space-x-3">
|
||||
<Avatar
|
||||
:image="evaluator.user_image"
|
||||
:label="evaluator.full_name"
|
||||
size="lg"
|
||||
/>
|
||||
<div>
|
||||
<div class="text-base font-semibold text-ink-gray-9">
|
||||
{{ evaluator.full_name }}
|
||||
</div>
|
||||
<div class="text-xs text-ink-gray-5">
|
||||
{{ evaluator.evaluator }}
|
||||
<div class="overflow-y-scroll">
|
||||
<div class="divide-y">
|
||||
<div
|
||||
v-for="evaluator in evaluators.data"
|
||||
@click="openProfile(evaluator.username)"
|
||||
class="cursor-pointer"
|
||||
>
|
||||
<div class="flex items-center justify-between py-3">
|
||||
<div class="flex items-center space-x-3">
|
||||
<Avatar
|
||||
:image="evaluator.user_image"
|
||||
:label="evaluator.full_name"
|
||||
size="lg"
|
||||
/>
|
||||
<div>
|
||||
<div class="text-base font-semibold text-ink-gray-9">
|
||||
{{ evaluator.full_name }}
|
||||
</div>
|
||||
<div class="text-xs text-ink-gray-5">
|
||||
{{ evaluator.evaluator }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,60 +1,55 @@
|
||||
<template>
|
||||
<div class="flex h-full flex-col">
|
||||
<div class="flex h-full flex-col relative">
|
||||
<div class="h-full pb-10" id="scrollContainer">
|
||||
<slot />
|
||||
</div>
|
||||
<div
|
||||
v-if="sidebarSettings.data"
|
||||
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"
|
||||
:style="{
|
||||
gridTemplateColumns: `repeat(${
|
||||
sidebarLinks.length + 1
|
||||
}, minmax(0, 1fr))`,
|
||||
}"
|
||||
>
|
||||
<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)"
|
||||
|
||||
<div class="relative z-20">
|
||||
<!-- Dropdown menu -->
|
||||
<div
|
||||
class="fixed bottom-16 right-2 w-[80%] rounded-md bg-surface-white text-base p-5 space-y-4 shadow-md"
|
||||
v-if="showMenu"
|
||||
ref="menu"
|
||||
>
|
||||
<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>
|
||||
<Popover
|
||||
trigger="hover"
|
||||
popoverClass="bottom-28 mx-2"
|
||||
placement="top-start"
|
||||
<div
|
||||
v-for="link in otherLinks"
|
||||
:key="link.label"
|
||||
class="flex items-center space-x-2 cursor-pointer"
|
||||
@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>
|
||||
|
||||
<!-- 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
|
||||
:is="icons['List']"
|
||||
class="h-6 w-6 stroke-1.5 text-ink-gray-5"
|
||||
/>
|
||||
</template>
|
||||
<template #body-main>
|
||||
<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>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -64,7 +59,6 @@ import { useRouter } from 'vue-router'
|
||||
import { watch, ref, onMounted } from 'vue'
|
||||
import { sessionStore } from '@/stores/session'
|
||||
import { usersStore } from '@/stores/user'
|
||||
import { Popover } from 'frappe-ui'
|
||||
import * as icons from 'lucide-vue-next'
|
||||
|
||||
const { logout, user, sidebarSettings } = sessionStore()
|
||||
@@ -73,26 +67,47 @@ const router = useRouter()
|
||||
let { userResource } = usersStore()
|
||||
const sidebarLinks = ref(getSidebarLinks())
|
||||
const otherLinks = ref([])
|
||||
const showMenu = ref(false)
|
||||
const menu = ref(null)
|
||||
|
||||
onMounted(() => {
|
||||
sidebarSettings.reload(
|
||||
{},
|
||||
{
|
||||
onSuccess(data) {
|
||||
Object.keys(data).forEach((key) => {
|
||||
if (!parseInt(data[key])) {
|
||||
sidebarLinks.value = sidebarLinks.value.filter(
|
||||
(link) => link.label.toLowerCase().split(' ').join('_') !== key
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
filterLinksToShow(data)
|
||||
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 = () => {
|
||||
if (user) {
|
||||
otherLinks.value.push({
|
||||
@@ -122,6 +137,7 @@ watch(userResource, () => {
|
||||
(userResource.data.is_moderator || userResource.data.is_instructor)
|
||||
) {
|
||||
addQuizzes()
|
||||
addAssignments()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -133,6 +149,14 @@ const addQuizzes = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const addAssignments = () => {
|
||||
otherLinks.value.push({
|
||||
label: 'Assignments',
|
||||
icon: 'Pencil',
|
||||
to: 'Assignments',
|
||||
})
|
||||
}
|
||||
|
||||
let isActive = (tab) => {
|
||||
return tab.activeFor?.includes(router.currentRoute.value.name)
|
||||
}
|
||||
@@ -158,4 +182,8 @@ const isVisible = (tab) => {
|
||||
else if (tab.label == 'Log out') return isLoggedIn
|
||||
else return true
|
||||
}
|
||||
|
||||
const toggleMenu = () => {
|
||||
showMenu.value = !showMenu.value
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
}"
|
||||
>
|
||||
<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">
|
||||
{{
|
||||
assignmentID === 'new'
|
||||
@@ -14,7 +14,7 @@
|
||||
: __('Edit Assignment')
|
||||
}}
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<div class="space-y-4 max-h-[75vh] overflow-y-auto">
|
||||
<FormControl
|
||||
v-model="assignment.title"
|
||||
:label="__('Title')"
|
||||
|
||||
192
frontend/src/components/Modals/EmailTemplateModal.vue
Normal file
192
frontend/src/components/Modals/EmailTemplateModal.vue
Normal 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>
|
||||
@@ -66,7 +66,7 @@
|
||||
</Dialog>
|
||||
</template>
|
||||
<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 { formatTime } from '@/utils/'
|
||||
|
||||
@@ -90,7 +90,7 @@ const props = defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
let evaluation = reactive({
|
||||
const evaluation = reactive({
|
||||
course: '',
|
||||
date: '',
|
||||
start_time: '',
|
||||
@@ -139,7 +139,7 @@ function submitEvaluation(close) {
|
||||
close()
|
||||
},
|
||||
onError(err) {
|
||||
let message = err.messages?.[0] || err
|
||||
const message = err.messages?.[0] || err
|
||||
let unavailabilityMessage
|
||||
|
||||
if (typeof message === 'string') {
|
||||
@@ -148,13 +148,13 @@ function submitEvaluation(close) {
|
||||
unavailabilityMessage = false
|
||||
}
|
||||
|
||||
toast.warning(__('Evaluator is unavailable'))
|
||||
toast.warning(__(unavailabilityMessage || 'Evaluator is unavailable'))
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const getCourses = () => {
|
||||
let courses = []
|
||||
const courses = []
|
||||
for (const course of props.courses) {
|
||||
if (course.evaluator) {
|
||||
courses.push({
|
||||
@@ -164,7 +164,7 @@ const getCourses = () => {
|
||||
}
|
||||
}
|
||||
|
||||
if (courses.length == 1) {
|
||||
if (courses.length === 1) {
|
||||
evaluation.course = courses[0].value
|
||||
}
|
||||
|
||||
|
||||
115
frontend/src/components/Modals/FeedbackModal.vue
Normal file
115
frontend/src/components/Modals/FeedbackModal.vue
Normal 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>
|
||||
@@ -15,26 +15,20 @@
|
||||
>
|
||||
<template #body-content>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div>
|
||||
<div class="mb-1.5 text-sm text-ink-gray-5">
|
||||
{{ __('Rating') }}
|
||||
</div>
|
||||
<Rating v-model="review.rating" />
|
||||
</div>
|
||||
<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>
|
||||
<Rating v-model="review.rating" :label="__('Rating')" />
|
||||
<FormControl
|
||||
:label="__('Review')"
|
||||
type="textarea"
|
||||
v-model="review.review"
|
||||
:rows="5"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Dialog, Textarea, createResource, toast } from 'frappe-ui'
|
||||
import { Dialog, FormControl, createResource, toast, Rating } from 'frappe-ui'
|
||||
import { reactive } from 'vue'
|
||||
import Rating from '@/components/Controls/Rating.vue'
|
||||
|
||||
const show = defineModel()
|
||||
const reviews = defineModel('reloadReviews')
|
||||
|
||||
@@ -51,6 +51,11 @@
|
||||
:label="activeTab.label"
|
||||
:description="activeTab.description"
|
||||
/>
|
||||
<EmailTemplates
|
||||
v-else-if="activeTab.label === 'Email Templates'"
|
||||
:label="activeTab.label"
|
||||
:description="activeTab.description"
|
||||
/>
|
||||
<PaymentSettings
|
||||
v-else-if="activeTab.label === 'Payment Gateway'"
|
||||
:label="activeTab.label"
|
||||
@@ -86,6 +91,7 @@ import SidebarLink from '@/components/SidebarLink.vue'
|
||||
import Members from '@/components/Members.vue'
|
||||
import Evaluators from '@/components/Evaluators.vue'
|
||||
import Categories from '@/components/Categories.vue'
|
||||
import EmailTemplates from '@/components/EmailTemplates.vue'
|
||||
import BrandSettings from '@/components/BrandSettings.vue'
|
||||
import PaymentSettings from '@/components/PaymentSettings.vue'
|
||||
|
||||
@@ -122,7 +128,7 @@ const tabsStructure = computed(() => {
|
||||
label: 'Enable Learning Paths',
|
||||
name: 'enable_learning_paths',
|
||||
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',
|
||||
},
|
||||
{
|
||||
@@ -139,11 +145,26 @@ const tabsStructure = computed(() => {
|
||||
'If enabled, it sends google calendar invite to the student for evaluations.',
|
||||
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',
|
||||
name: 'unsplash_access_key',
|
||||
description:
|
||||
'Optional. If this is set, students can pick a cover image from the unsplash library for their profile page. https://unsplash.com/documentation#getting-started.',
|
||||
'Allows users to pick a profile cover image from Unsplash. https://unsplash.com/documentation#getting-started.',
|
||||
type: 'password',
|
||||
},
|
||||
],
|
||||
@@ -160,6 +181,12 @@ const tabsStructure = computed(() => {
|
||||
description:
|
||||
'Configure the payment gateway and other payment related settings',
|
||||
fields: [
|
||||
{
|
||||
label: 'Default Currency',
|
||||
name: 'default_currency',
|
||||
type: 'Link',
|
||||
doctype: 'Currency',
|
||||
},
|
||||
{
|
||||
label: 'Payment Gateway',
|
||||
name: 'payment_gateway',
|
||||
@@ -167,10 +194,7 @@ const tabsStructure = computed(() => {
|
||||
doctype: 'Payment Gateway',
|
||||
},
|
||||
{
|
||||
label: 'Default Currency',
|
||||
name: 'default_currency',
|
||||
type: 'Link',
|
||||
doctype: 'Currency',
|
||||
type: 'Column Break',
|
||||
},
|
||||
{
|
||||
label: 'Apply GST for India',
|
||||
@@ -207,9 +231,14 @@ const tabsStructure = computed(() => {
|
||||
},
|
||||
{
|
||||
label: 'Categories',
|
||||
description: 'Manage the members of your learning system',
|
||||
description: 'Double click to edit the category',
|
||||
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',
|
||||
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',
|
||||
icon: 'LogIn',
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
/> -->
|
||||
</div>
|
||||
<div class="overflow-y-scroll">
|
||||
<div class="flex space-x-4">
|
||||
<SettingFields :fields="fields" :data="data.doc" class="w-1/2" />
|
||||
<div class="flex flex-col divide-y">
|
||||
<SettingFields :fields="fields" :data="data.doc" />
|
||||
<SettingFields
|
||||
v-if="paymentGateway.data"
|
||||
:fields="paymentGateway.data.fields"
|
||||
:data="paymentGateway.data.data"
|
||||
class="w-1/2"
|
||||
class="pt-5 my-0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -60,9 +60,28 @@ const paymentGateway = createResource({
|
||||
payment_gateway: props.data.doc.payment_gateway,
|
||||
}
|
||||
},
|
||||
transform(data) {
|
||||
arrangeFields(data.fields)
|
||||
return data
|
||||
},
|
||||
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({
|
||||
url: 'frappe.client.set_value',
|
||||
makeParams(values) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div v-for="(column, index) in columns" :key="index">
|
||||
<div
|
||||
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">
|
||||
<Link
|
||||
@@ -14,6 +14,7 @@
|
||||
v-model="data[field.name]"
|
||||
:doctype="field.doctype"
|
||||
:label="__(field.label)"
|
||||
:description="__(field.description)"
|
||||
/>
|
||||
|
||||
<div v-else-if="field.type == 'Code'">
|
||||
@@ -54,11 +55,11 @@
|
||||
<div v-else>
|
||||
<div class="flex items-center text-sm space-x-2">
|
||||
<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
|
||||
:src="data[field.name]?.file_url || data[field.name]"
|
||||
class="w-[80%] rounded"
|
||||
class="size-6 rounded"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col flex-wrap">
|
||||
|
||||
@@ -88,56 +88,61 @@
|
||||
:scrollToBottom="false"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="tab.label == 'Feedback'">
|
||||
<BatchFeedback :batch="batch.data.name" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Tabs>
|
||||
</div>
|
||||
<div class="p-5">
|
||||
<div class="text-ink-gray-7 font-semibold mb-4">
|
||||
{{ __('About this batch') }}:
|
||||
</div>
|
||||
<div
|
||||
v-html="batch.data.description"
|
||||
class="leading-5 mb-4 text-ink-gray-7"
|
||||
></div>
|
||||
|
||||
<div class="flex items-center avatar-group overlap mb-5">
|
||||
<div
|
||||
class="h-6 mr-1"
|
||||
:class="{
|
||||
'avatar-group overlap': batch.data.instructors.length > 1,
|
||||
}"
|
||||
>
|
||||
<UserAvatar
|
||||
v-for="instructor in batch.data.instructors"
|
||||
:user="instructor"
|
||||
/>
|
||||
<div class="mb-10">
|
||||
<div class="text-ink-gray-7 font-semibold mb-2">
|
||||
{{ __('About this batch') }}
|
||||
</div>
|
||||
<div
|
||||
v-html="batch.data.description"
|
||||
class="leading-5 mb-4 text-ink-gray-7"
|
||||
></div>
|
||||
|
||||
<div class="flex items-center avatar-group overlap mb-5">
|
||||
<div
|
||||
class="h-6 mr-1"
|
||||
:class="{
|
||||
'avatar-group overlap': batch.data.instructors.length > 1,
|
||||
}"
|
||||
>
|
||||
<UserAvatar
|
||||
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>
|
||||
<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 v-if="dayjs().isSameOrAfter(dayjs(batch.data.start_date))">
|
||||
<div class="text-ink-gray-7 font-semibold mb-2">
|
||||
{{ __('Feedback') }}
|
||||
</div>
|
||||
<BatchFeedback :batch="batch.data?.name" />
|
||||
</div>
|
||||
</div>
|
||||
<AnnouncementModal
|
||||
@@ -234,6 +239,7 @@ import Discussions from '@/components/Discussions.vue'
|
||||
import DateRange from '@/components/Common/DateRange.vue'
|
||||
import BulkCertificates from '@/components/Modals/BulkCertificates.vue'
|
||||
import BatchFeedback from '@/components/BatchFeedback.vue'
|
||||
import dayjs from 'dayjs/esm'
|
||||
|
||||
const user = inject('$user')
|
||||
const showAnnouncementModal = ref(false)
|
||||
@@ -277,11 +283,6 @@ const tabs = computed(() => {
|
||||
label: 'Discussions',
|
||||
icon: MessageCircle,
|
||||
})
|
||||
|
||||
batchTabs.push({
|
||||
label: 'Feedback',
|
||||
icon: ClipboardPen,
|
||||
})
|
||||
return batchTabs
|
||||
})
|
||||
|
||||
|
||||
@@ -37,14 +37,7 @@
|
||||
<BatchOverlay :batch="batch" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="grid lg:grid-cols-[60%,20%] gap-4 lg:gap-20 mt-10">
|
||||
<div class="order-2 lg:order-none">
|
||||
|
||||
</div>
|
||||
<div class="order-1 lg:order-none">
|
||||
<BatchOverlay :batch="batch" />
|
||||
</div>
|
||||
</div> -->
|
||||
<BatchOverlay :batch="batch" class="md:hidden mt-5" />
|
||||
<div v-if="batch.data.courses.length">
|
||||
<div class="flex items-center mt-10">
|
||||
<div class="text-2xl font-semibold">
|
||||
|
||||
@@ -153,6 +153,11 @@
|
||||
doctype="Email Template"
|
||||
:label="__('Email Template')"
|
||||
v-model="batch.confirmation_email_template"
|
||||
:onCreate="
|
||||
(value, close) => {
|
||||
openSettings('Email Templates', close)
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-5">
|
||||
|
||||
@@ -20,14 +20,12 @@
|
||||
</header>
|
||||
<div class="p-5 pb-10">
|
||||
<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"
|
||||
>
|
||||
<div class="text-lg text-ink-gray-9 font-semibold">
|
||||
{{ __('All Batches') }}
|
||||
</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"
|
||||
>
|
||||
<TabButtons
|
||||
@@ -115,12 +113,10 @@ const is_student = computed(() => user.data?.is_student)
|
||||
const currentTab = ref(is_student.value ? 'All' : 'Upcoming')
|
||||
const orderBy = ref('start_date')
|
||||
const readOnlyMode = window.read_only_mode
|
||||
const batchCount = ref(0)
|
||||
|
||||
onMounted(() => {
|
||||
setFiltersFromQuery()
|
||||
updateBatches()
|
||||
getBatchCount()
|
||||
categories.value = [
|
||||
{
|
||||
label: '',
|
||||
@@ -298,14 +294,6 @@ const canCreateBatch = () => {
|
||||
return false
|
||||
}
|
||||
|
||||
const getBatchCount = () => {
|
||||
call('frappe.client.get_count', {
|
||||
doctype: 'LMS Batch',
|
||||
}).then((data) => {
|
||||
batchCount.value = data
|
||||
})
|
||||
}
|
||||
|
||||
const breadcrumbs = computed(() => [
|
||||
{
|
||||
label: __('Batches'),
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
:text="__('Average Rating')"
|
||||
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">
|
||||
{{ course.data.rating }}
|
||||
</span>
|
||||
|
||||
@@ -20,14 +20,12 @@
|
||||
</header>
|
||||
<div class="p-5 pb-10">
|
||||
<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"
|
||||
>
|
||||
<div class="text-lg text-ink-gray-9 font-semibold">
|
||||
{{ __('All Courses') }}
|
||||
</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"
|
||||
>
|
||||
<TabButtons :buttons="courseTabs" v-model="currentTab" />
|
||||
@@ -172,6 +170,8 @@ const identifyUserPersona = async () => {
|
||||
}
|
||||
|
||||
const getCourseCount = () => {
|
||||
if (!user.data) return
|
||||
|
||||
call('frappe.client.get_count', {
|
||||
doctype: 'LMS Course',
|
||||
}).then((data) => {
|
||||
|
||||
@@ -561,3 +561,24 @@ export const openSettings = (category, close) => {
|
||||
settingsStore.activeTab = category
|
||||
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(/ /g, ' ')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, "'")
|
||||
.replace(/&/g, '&')
|
||||
.replace(/`/g, '`')
|
||||
.replace(/=/g, '=')
|
||||
.replace(///g, '/')
|
||||
.replace(/,/g, ',')
|
||||
.replace(/;/g, ';')
|
||||
.replace(/:/g, ':')
|
||||
}
|
||||
|
||||
@@ -356,6 +356,7 @@
|
||||
"fieldtype": "Section Break"
|
||||
}
|
||||
],
|
||||
"grid_page_length": 50,
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [
|
||||
{
|
||||
@@ -371,8 +372,8 @@
|
||||
"link_fieldname": "batch_name"
|
||||
}
|
||||
],
|
||||
"modified": "2025-02-18 15:43:18.512504",
|
||||
"modified_by": "Administrator",
|
||||
"modified": "2025-05-21 13:30:28.904260",
|
||||
"modified_by": "sayali@frappe.io",
|
||||
"module": "LMS",
|
||||
"name": "LMS Batch",
|
||||
"owner": "Administrator",
|
||||
@@ -412,8 +413,18 @@
|
||||
"role": "Batch Evaluator",
|
||||
"share": 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,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
|
||||
@@ -103,7 +103,7 @@ class LMSBatch(Document):
|
||||
frappe.throw(_("Seat count cannot be negative."))
|
||||
|
||||
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."))
|
||||
|
||||
def validate_timetable(self):
|
||||
|
||||
@@ -73,10 +73,11 @@
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"grid_page_length": 50,
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2025-01-13 19:02:58.259908",
|
||||
"modified_by": "Administrator",
|
||||
"modified": "2025-05-21 15:58:51.667270",
|
||||
"modified_by": "sayali@frappe.io",
|
||||
"module": "LMS",
|
||||
"name": "LMS Batch Feedback",
|
||||
"owner": "Administrator",
|
||||
@@ -106,7 +107,9 @@
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"row_format": "Dynamic",
|
||||
"sort_field": "creation",
|
||||
"sort_order": "DESC",
|
||||
"states": []
|
||||
"states": [],
|
||||
"title_field": "member"
|
||||
}
|
||||
@@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Frappe LMS VERSION\n"
|
||||
"Report-Msgid-Bugs-To: jannat@frappe.io\n"
|
||||
"POT-Creation-Date: 2025-05-16 16:04+0000\n"
|
||||
"PO-Revision-Date: 2025-05-16 16:04+0000\n"
|
||||
"POT-Creation-Date: 2025-05-23 16:04+0000\n"
|
||||
"PO-Revision-Date: 2025-05-23 16:04+0000\n"
|
||||
"Last-Translator: jannat@frappe.io\n"
|
||||
"Language-Team: jannat@frappe.io\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -50,6 +50,10 @@ msgstr ""
|
||||
msgid "<a href=\"https://docs.frappe.io/learning\">Documentation</a>"
|
||||
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
|
||||
#: lms/lms/workspace/lms/lms.json
|
||||
msgid "<span class=\"h4\"><b>Get Started</b></span>"
|
||||
@@ -77,7 +81,7 @@ msgstr ""
|
||||
msgid "About"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/Batch.vue:100
|
||||
#: frontend/src/pages/Batch.vue:98
|
||||
msgid "About this batch"
|
||||
msgstr ""
|
||||
|
||||
@@ -112,7 +116,7 @@ msgstr ""
|
||||
#: frontend/src/components/Assessments.vue:11
|
||||
#: frontend/src/components/BatchCourses.vue:11
|
||||
#: 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/LiveClass.vue:11
|
||||
#: frontend/src/components/Members.vue:44 frontend/src/pages/ProgramForm.vue:30
|
||||
@@ -146,7 +150,7 @@ msgstr ""
|
||||
msgid "Add a Student"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:557
|
||||
#: frontend/src/components/AppSidebar.vue:553
|
||||
msgid "Add a chapter"
|
||||
msgstr ""
|
||||
|
||||
@@ -158,7 +162,7 @@ msgstr ""
|
||||
msgid "Add a keyword and then press enter"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:558
|
||||
#: frontend/src/components/AppSidebar.vue:554
|
||||
msgid "Add a lesson"
|
||||
msgstr ""
|
||||
|
||||
@@ -183,11 +187,11 @@ msgstr ""
|
||||
msgid "Add at least one possible answer for this question: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:522
|
||||
#: frontend/src/components/AppSidebar.vue:518
|
||||
msgid "Add courses to your batch"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:502
|
||||
#: frontend/src/components/AppSidebar.vue:498
|
||||
msgid "Add students to your batch"
|
||||
msgstr ""
|
||||
|
||||
@@ -199,11 +203,11 @@ msgstr ""
|
||||
msgid "Add your assignment as {0}"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:438
|
||||
#: frontend/src/components/AppSidebar.vue:434
|
||||
msgid "Add your first chapter"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:453
|
||||
#: frontend/src/components/AppSidebar.vue:449
|
||||
msgid "Add your first lesson"
|
||||
msgstr ""
|
||||
|
||||
@@ -231,22 +235,18 @@ msgid "Admin"
|
||||
msgstr ""
|
||||
|
||||
#. 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"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/Batches.vue:27
|
||||
#: frontend/src/pages/Batches.vue:26
|
||||
msgid "All Batches"
|
||||
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"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/BatchFeedback.vue:51
|
||||
msgid "All Feedback"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/quiz/quiz.html:141
|
||||
msgid "All Submissions"
|
||||
msgstr ""
|
||||
@@ -286,7 +286,7 @@ msgstr ""
|
||||
#. Label of the amount (Currency) field in DocType 'LMS Batch'
|
||||
#. Label of the course_price (Currency) field in DocType 'LMS Course'
|
||||
#. 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_course/lms_course.json
|
||||
#: lms/lms/doctype/lms_payment/lms_payment.json
|
||||
@@ -344,11 +344,11 @@ msgstr ""
|
||||
msgid "Appears on the course card in the course list"
|
||||
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"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/BatchForm.vue:206
|
||||
#: frontend/src/pages/BatchForm.vue:211
|
||||
msgid "Appears when the batch URL is shared on socials"
|
||||
msgstr ""
|
||||
|
||||
@@ -383,7 +383,7 @@ msgstr ""
|
||||
msgid "Apps"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/Batches.vue:287
|
||||
#: frontend/src/pages/Batches.vue:283
|
||||
msgid "Archived"
|
||||
msgstr ""
|
||||
|
||||
@@ -423,7 +423,7 @@ msgid "Assessment {0} has already been added to this batch."
|
||||
msgstr ""
|
||||
|
||||
#. 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/BatchStudents.vue:68
|
||||
#: frontend/src/components/BatchStudents.vue:101
|
||||
@@ -484,7 +484,7 @@ msgstr ""
|
||||
msgid "Assignment will appear at the bottom of the lesson."
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:574
|
||||
#: frontend/src/components/AppSidebar.vue:570
|
||||
#: frontend/src/pages/Assignments.vue:211 lms/www/lms.py:273
|
||||
msgid "Assignments"
|
||||
msgstr ""
|
||||
@@ -517,15 +517,15 @@ msgstr ""
|
||||
msgid "Availability updated successfully"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/BatchFeedback.vue:43
|
||||
msgid "Average Feedback Received"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/CourseCard.vue:55
|
||||
#: frontend/src/pages/CourseDetail.vue:20
|
||||
msgid "Average Rating"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/BatchFeedback.vue:38
|
||||
msgid "Average of Feedback Received"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/Lesson.vue:166
|
||||
msgid "Back to Course"
|
||||
msgstr ""
|
||||
@@ -589,6 +589,10 @@ msgstr ""
|
||||
msgid "Batch Details Raw"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/EmailTemplateModal.vue:28
|
||||
msgid "Batch Enrollment Confirmation"
|
||||
msgstr ""
|
||||
|
||||
#. Name of a role
|
||||
#: lms/lms/doctype/course_evaluator/course_evaluator.json
|
||||
#: lms/lms/doctype/lms_batch/lms_batch.json
|
||||
@@ -653,7 +657,7 @@ msgid "Batch:"
|
||||
msgstr ""
|
||||
|
||||
#. 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
|
||||
msgid "Batches"
|
||||
msgstr ""
|
||||
@@ -752,19 +756,31 @@ msgstr ""
|
||||
#. Label of the category (Link) field in DocType 'LMS Batch'
|
||||
#. Label of the category (Data) field in DocType 'LMS Category'
|
||||
#. 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/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_category/lms_category.json
|
||||
#: lms/lms/doctype/lms_course/lms_course.json lms/templates/signup-form.html:22
|
||||
msgid "Category"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Categories.vue:23
|
||||
#: frontend/src/components/Categories.vue:39
|
||||
msgid "Category Name"
|
||||
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 a shortcut in the LMS Workspace
|
||||
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json
|
||||
@@ -804,13 +820,13 @@ msgstr ""
|
||||
#. Enrollment'
|
||||
#. Label of a Card Break 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/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: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/lms_batch/lms_batch.json
|
||||
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json
|
||||
@@ -946,6 +962,10 @@ msgstr ""
|
||||
msgid "Clearly Defined Role"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/BatchFeedback.vue:10
|
||||
msgid "Click here"
|
||||
msgstr ""
|
||||
|
||||
#: 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."
|
||||
msgstr ""
|
||||
@@ -960,7 +980,7 @@ msgstr ""
|
||||
msgid "Client Secret"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Categories.vue:12
|
||||
#: frontend/src/components/Categories.vue:27
|
||||
#: frontend/src/components/Evaluators.vue:24
|
||||
#: frontend/src/components/Members.vue:24
|
||||
msgid "Close"
|
||||
@@ -1197,6 +1217,8 @@ msgstr ""
|
||||
|
||||
#. Label of the content (Text) field in DocType 'Course Lesson'
|
||||
#. 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
|
||||
#: lms/lms/doctype/course_lesson/course_lesson.json
|
||||
#: lms/lms/doctype/lms_batch_feedback/lms_batch_feedback.json
|
||||
@@ -1488,15 +1510,15 @@ msgstr ""
|
||||
msgid "Create a Live Class"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:565
|
||||
#: frontend/src/components/AppSidebar.vue:561
|
||||
msgid "Create a batch"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:556
|
||||
#: frontend/src/components/AppSidebar.vue:552
|
||||
msgid "Create a course"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:566
|
||||
#: frontend/src/components/AppSidebar.vue:562
|
||||
msgid "Create a live class"
|
||||
msgstr ""
|
||||
|
||||
@@ -1504,15 +1526,15 @@ msgstr ""
|
||||
msgid "Create an Assignment"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:492
|
||||
#: frontend/src/components/AppSidebar.vue:488
|
||||
msgid "Create your first batch"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:426
|
||||
#: frontend/src/components/AppSidebar.vue:422
|
||||
msgid "Create your first course"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:471
|
||||
#: frontend/src/components/AppSidebar.vue:467
|
||||
msgid "Create your first quiz"
|
||||
msgstr ""
|
||||
|
||||
@@ -1520,18 +1542,18 @@ msgstr ""
|
||||
msgid "Created"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:562
|
||||
#: frontend/src/components/AppSidebar.vue:558
|
||||
msgid "Creating a batch"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:553
|
||||
#: frontend/src/components/AppSidebar.vue:549
|
||||
msgid "Creating a course"
|
||||
msgstr ""
|
||||
|
||||
#. 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 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_course/lms_course.json
|
||||
#: lms/lms/doctype/lms_payment/lms_payment.json
|
||||
@@ -1543,7 +1565,7 @@ msgstr ""
|
||||
msgid "Current Lesson"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:584
|
||||
#: frontend/src/components/AppSidebar.vue:580
|
||||
msgid "Custom Certificate Templates"
|
||||
msgstr ""
|
||||
|
||||
@@ -1623,6 +1645,10 @@ msgstr ""
|
||||
msgid "Dear "
|
||||
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'
|
||||
#: lms/lms/doctype/lms_settings/lms_settings.json
|
||||
msgid "Default Currency"
|
||||
@@ -1803,6 +1829,10 @@ msgstr ""
|
||||
msgid "Edit Chapter"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/EmailTemplateModal.vue:8
|
||||
msgid "Edit Email Template"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/Profile.vue:72
|
||||
msgid "Edit Profile"
|
||||
msgstr ""
|
||||
@@ -1844,11 +1874,23 @@ msgstr ""
|
||||
msgid "Email Template"
|
||||
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'
|
||||
#: lms/lms/doctype/lms_settings/lms_settings.json
|
||||
msgid "Email Templates"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/EmailTemplates.vue:128
|
||||
msgid "Email Templates deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the show_emails (Check) field in DocType 'LMS Settings'
|
||||
#: lms/lms/doctype/lms_settings/lms_settings.json
|
||||
msgid "Emails"
|
||||
@@ -1921,7 +1963,7 @@ msgstr ""
|
||||
msgid "Enroll Now"
|
||||
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"
|
||||
msgstr ""
|
||||
|
||||
@@ -1967,10 +2009,22 @@ msgstr ""
|
||||
msgid "Enter the correct answer"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/EmailTemplateModal.vue:122
|
||||
msgid "Error creating email template"
|
||||
msgstr ""
|
||||
|
||||
#: lms/lms/doctype/lms_batch/lms_batch.py:193
|
||||
msgid "Error creating live class. Please try again. {0}"
|
||||
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 shortcut in the LMS Workspace
|
||||
#: 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."
|
||||
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 (Link) field in DocType 'LMS Live Class'
|
||||
#: lms/lms/doctype/lms_badge/lms_badge.json
|
||||
@@ -2135,7 +2185,8 @@ msgid "Featured"
|
||||
msgstr ""
|
||||
|
||||
#. 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
|
||||
msgid "Feedback"
|
||||
msgstr ""
|
||||
@@ -2336,14 +2387,14 @@ msgstr ""
|
||||
msgid "Help"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/BatchFeedback.vue:11
|
||||
msgid "Help Us Improve"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/courses_created.html:15
|
||||
msgid "Help others learn something new by creating a course."
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/BatchFeedback.vue:15
|
||||
msgid "Help us improve by providing your feedback."
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/reviews.html:101
|
||||
msgid "Help us improve our course material."
|
||||
msgstr ""
|
||||
@@ -2585,8 +2636,8 @@ msgstr ""
|
||||
msgid "Interest"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:545
|
||||
#: frontend/src/components/AppSidebar.vue:548
|
||||
#: frontend/src/components/AppSidebar.vue:541
|
||||
#: frontend/src/components/AppSidebar.vue:544
|
||||
msgid "Introduction"
|
||||
msgstr ""
|
||||
|
||||
@@ -2624,7 +2675,7 @@ msgstr ""
|
||||
msgid "Invite Request"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:481
|
||||
#: frontend/src/components/AppSidebar.vue:477
|
||||
msgid "Invite your team and students"
|
||||
msgstr ""
|
||||
|
||||
@@ -2656,7 +2707,7 @@ msgstr ""
|
||||
msgid "Issue Date"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:581
|
||||
#: frontend/src/components/AppSidebar.vue:577
|
||||
msgid "Issue a Certificate"
|
||||
msgstr ""
|
||||
|
||||
@@ -2957,6 +3008,7 @@ msgstr ""
|
||||
#: lms/lms/doctype/lms_assignment/lms_assignment.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_batch/lms_batch.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_certificate/lms_certificate.json
|
||||
@@ -3116,9 +3168,9 @@ msgid "LiveCode URL"
|
||||
msgstr ""
|
||||
|
||||
#: 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/Courses.vue:77
|
||||
#: frontend/src/pages/Courses.vue:75
|
||||
#: frontend/src/pages/QuizSubmissionList.vue:39
|
||||
#: frontend/src/pages/Quizzes.vue:55
|
||||
msgid "Load More"
|
||||
@@ -3142,7 +3194,7 @@ msgid "Location Preference"
|
||||
msgstr ""
|
||||
|
||||
#: 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
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
@@ -3236,7 +3288,7 @@ msgid "Maximum Attempts"
|
||||
msgstr ""
|
||||
|
||||
#. 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
|
||||
msgid "Medium"
|
||||
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 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_settings/lms_settings.json
|
||||
msgid "Meta Image"
|
||||
@@ -3479,7 +3531,7 @@ msgstr ""
|
||||
msgid "Monday"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:589
|
||||
#: frontend/src/components/AppSidebar.vue:585
|
||||
msgid "Monetization"
|
||||
msgstr ""
|
||||
|
||||
@@ -3500,8 +3552,13 @@ msgstr ""
|
||||
msgid "My calendar"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/EmailTemplateModal.vue:24
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. 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/Members.vue:24 frontend/src/pages/Assignments.vue:19
|
||||
#: frontend/src/pages/Batches.vue:17 frontend/src/pages/Courses.vue:17
|
||||
@@ -3518,6 +3575,10 @@ msgstr ""
|
||||
msgid "New Course"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/EmailTemplateModal.vue:7
|
||||
msgid "New Email Template"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/Jobs.vue:23
|
||||
msgid "New Job"
|
||||
msgstr ""
|
||||
@@ -3617,7 +3678,7 @@ msgstr ""
|
||||
msgid "No courses under review"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/BatchFeedback.vue:101
|
||||
#: frontend/src/components/BatchFeedback.vue:60
|
||||
msgid "No feedback received yet."
|
||||
msgstr ""
|
||||
|
||||
@@ -3673,7 +3734,7 @@ msgstr ""
|
||||
msgid "Not Graded"
|
||||
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"
|
||||
msgstr ""
|
||||
|
||||
@@ -3842,7 +3903,7 @@ msgid "Pages"
|
||||
msgstr ""
|
||||
|
||||
#. 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
|
||||
msgid "Paid Batch"
|
||||
msgstr ""
|
||||
@@ -4084,7 +4145,7 @@ msgstr ""
|
||||
msgid "Please login to access the quiz."
|
||||
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."
|
||||
msgstr ""
|
||||
|
||||
@@ -4223,7 +4284,7 @@ msgid "Previous"
|
||||
msgstr ""
|
||||
|
||||
#. 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
|
||||
msgid "Pricing"
|
||||
msgstr ""
|
||||
@@ -4460,7 +4521,7 @@ msgstr ""
|
||||
msgid "Quiz will appear at the bottom of the lesson."
|
||||
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/Quizzes.vue:152 lms/www/lms.py:251
|
||||
msgid "Quizzes"
|
||||
@@ -4471,7 +4532,7 @@ msgstr ""
|
||||
#. Label of the rating (Rating) field in DocType 'LMS Course Review'
|
||||
#: frontend/src/components/CourseCardOverlay.vue:121
|
||||
#: 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_course/lms_course.json
|
||||
#: lms/lms/doctype/lms_course_review/lms_course_review.json
|
||||
@@ -4540,7 +4601,7 @@ msgstr ""
|
||||
msgid "Related Courses"
|
||||
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"
|
||||
msgstr ""
|
||||
|
||||
@@ -4578,7 +4639,7 @@ msgstr ""
|
||||
|
||||
#. Label of the review (Small Text) field in DocType 'LMS Course Review'
|
||||
#. 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/workspace/lms/lms.json lms/templates/reviews.html:143
|
||||
msgid "Review"
|
||||
@@ -4613,7 +4674,7 @@ msgstr ""
|
||||
msgid "Role updated successfully"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:601
|
||||
#: frontend/src/components/AppSidebar.vue:597
|
||||
msgid "Roles"
|
||||
msgstr ""
|
||||
|
||||
@@ -4678,6 +4739,7 @@ msgstr ""
|
||||
#: frontend/src/components/Assignment.vue:46
|
||||
#: frontend/src/components/Controls/CodeEditor.vue:25
|
||||
#: 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:129
|
||||
#: frontend/src/pages/BatchForm.vue:8 frontend/src/pages/CourseForm.vue:17
|
||||
@@ -4729,7 +4791,7 @@ msgstr ""
|
||||
msgid "Search by Name"
|
||||
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"
|
||||
msgstr ""
|
||||
|
||||
@@ -4796,15 +4858,15 @@ msgstr ""
|
||||
msgid "Set your Password"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:549
|
||||
#: frontend/src/components/AppSidebar.vue:545
|
||||
msgid "Setting up"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:594
|
||||
#: frontend/src/components/AppSidebar.vue:590
|
||||
msgid "Setting up payment gateway"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:599
|
||||
#: frontend/src/components/AppSidebar.vue:595
|
||||
#: frontend/src/components/Modals/Settings.vue:7
|
||||
#: frontend/src/pages/BatchForm.vue:46 frontend/src/pages/CourseForm.vue:143
|
||||
#: frontend/src/pages/ProfileRoles.vue:4 frontend/src/pages/QuizForm.vue:79
|
||||
@@ -5132,6 +5194,7 @@ msgid "Subgroup"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/AnnouncementModal.vue:20
|
||||
#: frontend/src/components/Modals/EmailTemplateModal.vue:31
|
||||
msgid "Subject"
|
||||
msgstr ""
|
||||
|
||||
@@ -5156,7 +5219,6 @@ msgstr ""
|
||||
msgid "Submission by"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/BatchFeedback.vue:14
|
||||
#: frontend/src/components/Modals/AssessmentModal.vue:9
|
||||
#: frontend/src/components/Modals/BatchCourseModal.vue:9
|
||||
#: frontend/src/components/Modals/EvaluationModal.vue:9
|
||||
@@ -5168,6 +5230,10 @@ msgstr ""
|
||||
msgid "Submit"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/BatchFeedback.vue:35
|
||||
msgid "Submit Feedback"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/PersonaForm.vue:43
|
||||
msgid "Submit and Continue"
|
||||
msgstr ""
|
||||
@@ -5305,8 +5371,8 @@ msgstr ""
|
||||
msgid "Text"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/BatchFeedback.vue:7
|
||||
msgid "Thank you for providing your feedback!"
|
||||
#: frontend/src/components/BatchFeedback.vue:6
|
||||
msgid "Thank you for providing your feedback."
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/emails/lms_course_interest.html:17
|
||||
@@ -5584,6 +5650,10 @@ msgstr ""
|
||||
msgid "Total Signups"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/FeedbackModal.vue:11
|
||||
msgid "Training Feedback"
|
||||
msgstr ""
|
||||
|
||||
#. Option for the 'Location Preference' (Select) field in DocType 'User'
|
||||
#: lms/fixtures/custom_field.json
|
||||
msgid "Travel"
|
||||
@@ -5662,7 +5732,7 @@ msgstr ""
|
||||
msgid "Unlisted"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/Batches.vue:288
|
||||
#: frontend/src/pages/Batches.vue:284
|
||||
msgid "Unpublished"
|
||||
msgstr ""
|
||||
|
||||
@@ -5684,14 +5754,14 @@ msgstr ""
|
||||
#. Option for the 'Status' (Select) field in DocType 'Cohort'
|
||||
#. Option for the 'Status' (Select) field in DocType 'LMS Certificate Request'
|
||||
#. 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
|
||||
#: lms/lms/doctype/lms_certificate_request/lms_certificate_request.json
|
||||
#: lms/lms/doctype/lms_course/lms_course.json
|
||||
msgid "Upcoming"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/pages/Batch.vue:179
|
||||
#: frontend/src/pages/Batch.vue:184
|
||||
msgid "Upcoming Batches"
|
||||
msgstr ""
|
||||
|
||||
@@ -5700,7 +5770,7 @@ msgstr ""
|
||||
msgid "Upcoming Evaluations"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/BrandSettings.vue:23
|
||||
#: frontend/src/components/BrandSettings.vue:24
|
||||
#: frontend/src/components/PaymentSettings.vue:27
|
||||
#: frontend/src/components/SettingDetails.vue:23
|
||||
msgid "Update"
|
||||
@@ -5710,7 +5780,7 @@ msgstr ""
|
||||
msgid "Update Password"
|
||||
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"
|
||||
msgstr ""
|
||||
|
||||
@@ -5722,6 +5792,10 @@ msgstr ""
|
||||
msgid "Uploading {0}%"
|
||||
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 email (Link) field in DocType 'Cohort Staff'
|
||||
#. Label of the user (Link) field in DocType 'LMS Course Interest'
|
||||
@@ -5807,6 +5881,10 @@ msgstr ""
|
||||
msgid "View Certificate"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/BatchFeedback.vue:56
|
||||
msgid "View all feedback"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the visibility (Select) field in DocType 'LMS Batch Old'
|
||||
#: lms/lms/doctype/lms_batch_old/lms_batch_old.json
|
||||
msgid "Visibility"
|
||||
@@ -5945,7 +6023,7 @@ msgstr ""
|
||||
msgid "You are already enrolled for this course."
|
||||
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."
|
||||
msgstr ""
|
||||
|
||||
@@ -6095,6 +6173,10 @@ msgstr ""
|
||||
msgid "Your class on {0} is today"
|
||||
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/templates/emails/certificate_request_notification.html:3
|
||||
msgid "Your evaluation for the course {0} has been scheduled on {1} at {2} {3}."
|
||||
@@ -6209,10 +6291,18 @@ msgstr ""
|
||||
msgid "ratings"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/Categories.vue:19
|
||||
msgid "saving..."
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/reviews.html:43
|
||||
msgid "stars"
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/BatchFeedback.vue:12
|
||||
msgid "to view your feedback."
|
||||
msgstr ""
|
||||
|
||||
#: frontend/src/components/StudentHeatmap.vue:10
|
||||
msgid "weeks"
|
||||
msgstr ""
|
||||
|
||||
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: frappe\n"
|
||||
"Report-Msgid-Bugs-To: jannat@frappe.io\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"
|
||||
"Language-Team: Serbian (Latin)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -251,7 +251,7 @@ msgstr ""
|
||||
|
||||
#: lms/templates/quiz/quiz.html:141
|
||||
msgid "All Submissions"
|
||||
msgstr "Svi podneti podaci"
|
||||
msgstr "Sve podneseno"
|
||||
|
||||
#: lms/lms/doctype/lms_quiz/lms_quiz.py:44
|
||||
msgid "All questions should have the same marks if the limit is set."
|
||||
@@ -502,7 +502,7 @@ msgstr ""
|
||||
|
||||
#: frontend/src/pages/ProfileEvaluator.vue:137
|
||||
msgid "Authorize Google Calendar Access"
|
||||
msgstr ""
|
||||
msgstr "Odobri pristup Google Calendar-u"
|
||||
|
||||
#. Option for the 'Event' (Select) field in DocType 'LMS Badge'
|
||||
#: lms/lms/doctype/lms_badge/lms_badge.json
|
||||
@@ -687,7 +687,7 @@ msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/EditProfile.vue:75
|
||||
msgid "Bio"
|
||||
msgstr ""
|
||||
msgstr "Biografija"
|
||||
|
||||
#. Label of the body (Markdown Editor) field in DocType 'Course Lesson'
|
||||
#: lms/lms/doctype/course_lesson/course_lesson.json
|
||||
@@ -765,7 +765,7 @@ msgstr "Kategorija"
|
||||
|
||||
#: frontend/src/components/Categories.vue:23
|
||||
msgid "Category Name"
|
||||
msgstr ""
|
||||
msgstr "Naziv kategorije"
|
||||
|
||||
#. Label of the certificate (Link) field in DocType 'LMS Enrollment'
|
||||
#. 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
|
||||
msgid "Check"
|
||||
msgstr ""
|
||||
msgstr "Označi"
|
||||
|
||||
#: lms/templates/emails/mention_template.html:10
|
||||
msgid "Check Discussion"
|
||||
@@ -955,12 +955,12 @@ msgstr ""
|
||||
#. Label of the client_id (Data) field in DocType 'Zoom Settings'
|
||||
#: lms/lms/doctype/zoom_settings/zoom_settings.json
|
||||
msgid "Client ID"
|
||||
msgstr ""
|
||||
msgstr "ID klijenta"
|
||||
|
||||
#. Label of the client_secret (Password) field in DocType 'Zoom Settings'
|
||||
#: lms/lms/doctype/zoom_settings/zoom_settings.json
|
||||
msgid "Client Secret"
|
||||
msgstr ""
|
||||
msgstr "Tajna klijenta"
|
||||
|
||||
#: frontend/src/components/Categories.vue:12
|
||||
#: frontend/src/components/Evaluators.vue:24
|
||||
@@ -983,7 +983,7 @@ msgstr ""
|
||||
#. Label of the code (Code) field in DocType 'LMS Exercise'
|
||||
#: lms/lms/doctype/lms_exercise/lms_exercise.json
|
||||
msgid "Code"
|
||||
msgstr ""
|
||||
msgstr "Šifra"
|
||||
|
||||
#. Name of a DocType
|
||||
#. 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'
|
||||
#: lms/lms/doctype/lms_batch/lms_batch.json
|
||||
msgid "Confirmation Email Template"
|
||||
msgstr ""
|
||||
msgstr "Šablon imejla za potvrdu"
|
||||
|
||||
#: lms/lms/doctype/lms_certificate/lms_certificate.py:29
|
||||
msgid "Congratulations on getting certified!"
|
||||
@@ -1744,7 +1744,7 @@ msgstr ""
|
||||
#: lms/lms/doctype/lms_assignment/lms_assignment.json
|
||||
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json
|
||||
msgid "Document"
|
||||
msgstr ""
|
||||
msgstr "Dokument"
|
||||
|
||||
#: lms/templates/emails/payment_reminder.html:11
|
||||
msgid "Don’t 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/Profile.vue:36 frontend/src/pages/Programs.vue:53
|
||||
msgid "Edit"
|
||||
msgstr "Izmeni"
|
||||
msgstr "Uredi"
|
||||
|
||||
#: frontend/src/components/Modals/AssignmentForm.vue:14
|
||||
msgid "Edit Assignment"
|
||||
@@ -1840,7 +1840,7 @@ msgstr ""
|
||||
#. Label of the email_sent (Check) field in DocType 'LMS Course Interest'
|
||||
#: lms/lms/doctype/lms_course_interest/lms_course_interest.json
|
||||
msgid "Email Sent"
|
||||
msgstr ""
|
||||
msgstr "Imejl poslat"
|
||||
|
||||
#: frontend/src/pages/BatchForm.vue:154
|
||||
msgid "Email Template"
|
||||
@@ -1864,7 +1864,7 @@ msgstr "Zaposleno lice"
|
||||
#. Label of the enable (Check) field in DocType 'Zoom Settings'
|
||||
#: lms/lms/doctype/zoom_settings/zoom_settings.json
|
||||
msgid "Enable"
|
||||
msgstr ""
|
||||
msgstr "Omogući"
|
||||
|
||||
#: lms/lms/doctype/lms_settings/lms_settings.py:21
|
||||
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'
|
||||
#: lms/lms/doctype/lms_badge/lms_badge.json
|
||||
msgid "Field To Check"
|
||||
msgstr ""
|
||||
msgstr "Polje za proveru"
|
||||
|
||||
#. Label of the major (Data) field in DocType 'Education Detail'
|
||||
#: lms/lms/doctype/education_detail/education_detail.json
|
||||
@@ -2293,7 +2293,7 @@ msgstr ""
|
||||
#. Request'
|
||||
#: lms/lms/doctype/lms_certificate_request/lms_certificate_request.json
|
||||
msgid "Google Meet Link"
|
||||
msgstr ""
|
||||
msgstr "Google Meet Link"
|
||||
|
||||
#. Label of the grade (Data) field in DocType 'Education Detail'
|
||||
#: frontend/src/components/Assignment.vue:158
|
||||
@@ -2475,7 +2475,7 @@ msgstr ""
|
||||
#: lms/lms/doctype/lms_badge/lms_badge.json
|
||||
#: lms/lms/doctype/lms_exercise/lms_exercise.json
|
||||
msgid "Image"
|
||||
msgstr ""
|
||||
msgstr "Slika"
|
||||
|
||||
#: frontend/src/components/Modals/EditCoverImage.vue:58
|
||||
#: frontend/src/components/UnsplashImageBrowser.vue:52
|
||||
@@ -3369,7 +3369,7 @@ msgstr ""
|
||||
#. Group in LMS Batch Old's connections
|
||||
#: lms/lms/doctype/lms_batch_old/lms_batch_old.json
|
||||
msgid "Members"
|
||||
msgstr ""
|
||||
msgstr "Članovi"
|
||||
|
||||
#. Label of the membership (Select) field in DocType 'LMS Batch Old'
|
||||
#: lms/lms/doctype/lms_batch_old/lms_batch_old.json
|
||||
@@ -3659,7 +3659,7 @@ msgstr "Nije dozvoljeno"
|
||||
#. Submission'
|
||||
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json
|
||||
msgid "Not Applicable"
|
||||
msgstr "Nije primenljivo"
|
||||
msgstr "Nije primenjivo"
|
||||
|
||||
#: lms/templates/assessments.html:48
|
||||
msgid "Not Attempted"
|
||||
@@ -3707,7 +3707,7 @@ msgstr ""
|
||||
#. Label of the sb_00 (Section Break) field in DocType 'Zoom Settings'
|
||||
#: lms/lms/doctype/zoom_settings/zoom_settings.json
|
||||
msgid "OAuth Client ID"
|
||||
msgstr ""
|
||||
msgstr "OAuth ID klijenta"
|
||||
|
||||
#. Option for the 'Location Preference' (Select) field in DocType 'User'
|
||||
#: lms/fixtures/custom_field.json
|
||||
@@ -3997,7 +3997,7 @@ msgstr "Na čekanju"
|
||||
#: frontend/src/pages/QuizSubmissionList.vue:102
|
||||
#: lms/lms/doctype/lms_quiz_submission/lms_quiz_submission.json
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
msgstr "Procenat"
|
||||
|
||||
#. Option for the 'Grade Type' (Select) field in DocType 'Education Detail'
|
||||
#: lms/lms/doctype/education_detail/education_detail.json
|
||||
@@ -4214,7 +4214,7 @@ msgstr ""
|
||||
#. Label of the image (Attach Image) field in DocType 'LMS Course'
|
||||
#: lms/lms/doctype/lms_course/lms_course.json
|
||||
msgid "Preview Image"
|
||||
msgstr ""
|
||||
msgstr "Pregled slike"
|
||||
|
||||
#: frontend/src/pages/CourseForm.vue:195
|
||||
msgid "Preview Video"
|
||||
@@ -4345,7 +4345,7 @@ msgstr ""
|
||||
#: frontend/src/pages/CourseForm.vue:154
|
||||
#: lms/lms/doctype/lms_course/lms_course.json
|
||||
msgid "Published On"
|
||||
msgstr ""
|
||||
msgstr "Objavljeno na"
|
||||
|
||||
#. Label of the purchased_certificate (Check) field in DocType 'LMS Enrollment'
|
||||
#: lms/lms/doctype/lms_enrollment/lms_enrollment.json
|
||||
@@ -4494,7 +4494,7 @@ msgstr ""
|
||||
#. Timetable'
|
||||
#: lms/lms/doctype/lms_batch_timetable/lms_batch_timetable.json
|
||||
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 Timetable
|
||||
@@ -4502,7 +4502,7 @@ msgstr ""
|
||||
#: lms/lms/doctype/lms_batch_timetable/lms_batch_timetable.json
|
||||
#: lms/lms/doctype/lms_timetable_legend/lms_timetable_legend.json
|
||||
msgid "Reference DocType"
|
||||
msgstr ""
|
||||
msgstr "DocType referenca"
|
||||
|
||||
#. Label of the reference_doctype (Link) field in DocType 'LMS Badge'
|
||||
#: lms/lms/doctype/lms_badge/lms_badge.json
|
||||
@@ -4597,7 +4597,7 @@ msgstr ""
|
||||
|
||||
#: lms/templates/reviews.html:4
|
||||
msgid "Reviews"
|
||||
msgstr ""
|
||||
msgstr "Pregledi"
|
||||
|
||||
#. Label of the role (Select) field in DocType 'Cohort Staff'
|
||||
#. 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'
|
||||
#: lms/lms/doctype/cohort_web_page/cohort_web_page.json
|
||||
msgid "Scope"
|
||||
msgstr ""
|
||||
msgstr "Opseg"
|
||||
|
||||
#. Label of the score (Int) field in DocType 'LMS Quiz Submission'
|
||||
#: frontend/src/pages/QuizSubmission.vue:39
|
||||
@@ -4878,12 +4878,12 @@ msgstr ""
|
||||
#. Label of the sidebar_tab (Tab Break) field in DocType 'LMS Settings'
|
||||
#: lms/lms/doctype/lms_settings/lms_settings.json
|
||||
msgid "Sidebar"
|
||||
msgstr ""
|
||||
msgstr "Bočna traka"
|
||||
|
||||
#. Label of the sidebar_items (Table) field in DocType 'LMS Settings'
|
||||
#: lms/lms/doctype/lms_settings/lms_settings.json
|
||||
msgid "Sidebar Items"
|
||||
msgstr ""
|
||||
msgstr "Stavke bočne trake"
|
||||
|
||||
#: lms/lms/user.py:29
|
||||
msgid "Sign Up is disabled"
|
||||
@@ -5056,7 +5056,7 @@ msgstr "Stanje"
|
||||
#: lms/lms/doctype/lms_course/lms_course.json
|
||||
#: lms/lms/doctype/lms_settings/lms_settings.json lms/www/lms.py:204
|
||||
msgid "Statistics"
|
||||
msgstr ""
|
||||
msgstr "Statistika"
|
||||
|
||||
#. Label of the status (Select) field in DocType 'Job Opportunity'
|
||||
#. Label of the status (Select) field in DocType 'Cohort'
|
||||
@@ -5135,7 +5135,7 @@ msgstr ""
|
||||
|
||||
#: frontend/src/components/Modals/AnnouncementModal.vue:20
|
||||
msgid "Subject"
|
||||
msgstr "Predmet"
|
||||
msgstr "Naslov"
|
||||
|
||||
#: frontend/src/components/Modals/AnnouncementModal.vue:93
|
||||
msgid "Subject is required"
|
||||
@@ -5305,7 +5305,7 @@ msgstr ""
|
||||
#: lms/lms/doctype/lms_assignment/lms_assignment.json
|
||||
#: lms/lms/doctype/lms_assignment_submission/lms_assignment_submission.json
|
||||
msgid "Text"
|
||||
msgstr ""
|
||||
msgstr "Tekst"
|
||||
|
||||
#: frontend/src/components/BatchFeedback.vue:7
|
||||
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_submission/lms_assignment_submission.json
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
msgstr "URL"
|
||||
|
||||
#. Label of the unavailability_section (Section Break) field in DocType 'Course
|
||||
#. Evaluator'
|
||||
@@ -5741,12 +5741,12 @@ msgstr ""
|
||||
#. Label of the user_field (Select) field in DocType 'LMS Badge'
|
||||
#: lms/lms/doctype/lms_badge/lms_badge.json
|
||||
msgid "User Field"
|
||||
msgstr ""
|
||||
msgstr "Korisničko polje"
|
||||
|
||||
#. Label of the user_image (Attach Image) field in DocType 'Course Evaluator'
|
||||
#: lms/lms/doctype/course_evaluator/course_evaluator.json
|
||||
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 Quiz Question'
|
||||
@@ -5812,7 +5812,7 @@ msgstr ""
|
||||
#. Label of the visibility (Select) field in DocType 'LMS Batch Old'
|
||||
#: lms/lms/doctype/lms_batch_old/lms_batch_old.json
|
||||
msgid "Visibility"
|
||||
msgstr ""
|
||||
msgstr "Vidljivost"
|
||||
|
||||
#: frontend/src/components/BatchOverlay.vue:69
|
||||
msgid "Visit Batch"
|
||||
@@ -6157,7 +6157,7 @@ msgstr ""
|
||||
|
||||
#: frontend/src/pages/CertifiedParticipants.vue:82
|
||||
msgid "certificate"
|
||||
msgstr ""
|
||||
msgstr "sertifikat"
|
||||
|
||||
#: frontend/src/pages/CertifiedParticipants.vue:81
|
||||
msgid "certificates"
|
||||
|
||||
104
lms/locale/zh.po
104
lms/locale/zh.po
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: frappe\n"
|
||||
"Report-Msgid-Bugs-To: jannat@frappe.io\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"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -109,7 +109,7 @@ msgstr "激活"
|
||||
|
||||
#: frontend/src/pages/Statistics.vue:16
|
||||
msgid "Active Members"
|
||||
msgstr ""
|
||||
msgstr "活跃成员"
|
||||
|
||||
#: frontend/src/components/Assessments.vue:11
|
||||
#: frontend/src/components/BatchCourses.vue:11
|
||||
@@ -329,7 +329,7 @@ msgstr "公告发送成功"
|
||||
|
||||
#: frontend/src/components/Modals/AnnouncementModal.vue:96
|
||||
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
|
||||
@@ -352,7 +352,7 @@ msgstr "在分享批次链接至网络平台时显示"
|
||||
|
||||
#: frontend/src/pages/BatchForm.vue:206
|
||||
msgid "Appears when the batch URL is shared on socials"
|
||||
msgstr ""
|
||||
msgstr "当班级URL在社交平台分享时显示"
|
||||
|
||||
#: frontend/src/pages/JobDetail.vue:51
|
||||
msgid "Apply"
|
||||
@@ -475,7 +475,7 @@ msgstr "学员{1}的课时{0}作业已存在。"
|
||||
|
||||
#: frontend/src/components/Assignment.vue:356
|
||||
msgid "Assignment submitted successfully"
|
||||
msgstr ""
|
||||
msgstr "作业提交成功。"
|
||||
|
||||
#: frontend/src/components/Modals/AssignmentForm.vue:138
|
||||
msgid "Assignment updated successfully"
|
||||
@@ -517,7 +517,7 @@ msgstr "自动录制"
|
||||
|
||||
#: frontend/src/pages/ProfileEvaluator.vue:224
|
||||
msgid "Availability updated successfully"
|
||||
msgstr ""
|
||||
msgstr "可用性更新成功。"
|
||||
|
||||
#: frontend/src/components/CourseCard.vue:55
|
||||
#: frontend/src/pages/CourseDetail.vue:20
|
||||
@@ -640,7 +640,7 @@ msgstr "批次结束日期不可早于开始日期"
|
||||
|
||||
#: lms/lms/api.py:246
|
||||
msgid "Batch has already started."
|
||||
msgstr ""
|
||||
msgstr "班级已开始。"
|
||||
|
||||
#: lms/lms/api.py:241
|
||||
msgid "Batch is sold out."
|
||||
@@ -648,7 +648,7 @@ msgstr "该批次已满额。"
|
||||
|
||||
#: lms/lms/doctype/lms_batch/lms_batch.py:46
|
||||
msgid "Batch start time cannot be greater than or equal to end time."
|
||||
msgstr ""
|
||||
msgstr "班级开始时间不可大于或等于结束时间。"
|
||||
|
||||
#: lms/templates/emails/batch_start_reminder.html:10
|
||||
msgid "Batch:"
|
||||
@@ -873,7 +873,7 @@ msgstr "章节添加成功"
|
||||
|
||||
#: frontend/src/components/CourseOutline.vue:290
|
||||
msgid "Chapter deleted successfully"
|
||||
msgstr ""
|
||||
msgstr "章节删除成功。"
|
||||
|
||||
#: frontend/src/components/Modals/ChapterModal.vue:196
|
||||
msgid "Chapter updated successfully"
|
||||
@@ -894,7 +894,7 @@ msgstr "查看讨论"
|
||||
|
||||
#: frontend/src/components/Modals/AssignmentForm.vue:55
|
||||
msgid "Check Submissions"
|
||||
msgstr ""
|
||||
msgstr "查看提交记录"
|
||||
|
||||
#: lms/templates/certificates_section.html:24
|
||||
msgid "Check out the {0} to know more about certification."
|
||||
@@ -917,7 +917,7 @@ msgstr "选择所有适用答案"
|
||||
|
||||
#: frontend/src/components/Modals/Question.vue:19
|
||||
msgid "Choose an existing question"
|
||||
msgstr ""
|
||||
msgstr "选择现有题目"
|
||||
|
||||
#: frontend/src/components/Controls/IconPicker.vue:27
|
||||
msgid "Choose an icon"
|
||||
@@ -1068,7 +1068,7 @@ msgstr "评估人评语"
|
||||
#. Settings'
|
||||
#: lms/lms/doctype/lms_settings/lms_settings.json
|
||||
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 'Work Experience'
|
||||
@@ -1171,7 +1171,7 @@ msgstr "执行评估"
|
||||
|
||||
#: frontend/src/pages/BatchForm.vue:141
|
||||
msgid "Configurations"
|
||||
msgstr ""
|
||||
msgstr "系统配置"
|
||||
|
||||
#: frontend/src/components/UserDropdown.vue:180
|
||||
msgid "Confirm"
|
||||
@@ -1327,7 +1327,7 @@ msgstr "课程完成"
|
||||
|
||||
#: frontend/src/pages/Statistics.vue:31
|
||||
msgid "Course Completions"
|
||||
msgstr ""
|
||||
msgstr "课程完成情况"
|
||||
|
||||
#. Name of a role
|
||||
#: frontend/src/pages/ProfileRoles.vue:26
|
||||
@@ -1352,7 +1352,7 @@ msgstr "课程描述"
|
||||
|
||||
#: frontend/src/pages/Statistics.vue:22
|
||||
msgid "Course Enrollments"
|
||||
msgstr ""
|
||||
msgstr "课程注册记录"
|
||||
|
||||
#. Name of a DocType
|
||||
#: lms/lms/doctype/course_evaluator/course_evaluator.json
|
||||
@@ -1419,7 +1419,7 @@ msgstr "课程已添加至项目"
|
||||
|
||||
#: frontend/src/pages/CourseForm.vue:468
|
||||
msgid "Course created successfully"
|
||||
msgstr ""
|
||||
msgstr "课程创建成功。"
|
||||
|
||||
#: frontend/src/pages/CourseForm.vue:489
|
||||
msgid "Course deleted successfully"
|
||||
@@ -1431,7 +1431,7 @@ msgstr "课程移动成功"
|
||||
|
||||
#: frontend/src/pages/CourseForm.vue:451
|
||||
msgid "Course updated successfully"
|
||||
msgstr ""
|
||||
msgstr "课程更新成功。"
|
||||
|
||||
#: lms/lms/doctype/lms_batch/lms_batch.py:54
|
||||
#: lms/lms/doctype/lms_program/lms_program.py:19
|
||||
@@ -2047,7 +2047,7 @@ msgstr "付费证书需指定评估人"
|
||||
|
||||
#: frontend/src/components/Modals/EvaluationModal.vue:151
|
||||
msgid "Evaluator is unavailable"
|
||||
msgstr ""
|
||||
msgstr "评估人不可用"
|
||||
|
||||
#. Label of the event (Select) field in DocType 'LMS Badge'
|
||||
#. Label of the event (Link) field in DocType 'LMS Live Class'
|
||||
@@ -2352,7 +2352,7 @@ msgstr "帮助我们改进课程材料"
|
||||
|
||||
#: frontend/src/pages/PersonaForm.vue:16
|
||||
msgid "Help us understand your needs"
|
||||
msgstr ""
|
||||
msgstr "请说明您的需求"
|
||||
|
||||
#: lms/lms/notification/certificate_request_reminder/certificate_request_reminder.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'
|
||||
#: lms/lms/doctype/lms_settings/lms_settings.json
|
||||
msgid "Identify User Category"
|
||||
msgstr ""
|
||||
msgstr "识别用户类别"
|
||||
|
||||
#: 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."
|
||||
@@ -3038,19 +3038,19 @@ msgstr "课时标题"
|
||||
|
||||
#: frontend/src/pages/LessonForm.vue:414
|
||||
msgid "Lesson created successfully"
|
||||
msgstr ""
|
||||
msgstr "课时创建成功。"
|
||||
|
||||
#: frontend/src/components/CourseOutline.vue:217
|
||||
msgid "Lesson deleted successfully"
|
||||
msgstr ""
|
||||
msgstr "课时删除成功。"
|
||||
|
||||
#: frontend/src/components/CourseOutline.vue:232
|
||||
msgid "Lesson moved successfully"
|
||||
msgstr ""
|
||||
msgstr "课时移动成功。"
|
||||
|
||||
#: frontend/src/pages/LessonForm.vue:438
|
||||
msgid "Lesson updated successfully"
|
||||
msgstr ""
|
||||
msgstr "课时更新成功。"
|
||||
|
||||
#. Label of the lessons (Table) field in DocType 'Course Chapter'
|
||||
#. Group in Course Chapter's connections
|
||||
@@ -3429,7 +3429,7 @@ msgstr "元图片"
|
||||
#. Label of the meta_keywords (Small Text) field in DocType 'LMS Settings'
|
||||
#: lms/lms/doctype/lms_settings/lms_settings.json
|
||||
msgid "Meta Keywords"
|
||||
msgstr ""
|
||||
msgstr "元关键词"
|
||||
|
||||
#. Label of the milestone (Check) field in DocType 'LMS Batch Timetable'
|
||||
#: lms/lms/doctype/lms_batch_timetable/lms_batch_timetable.json
|
||||
@@ -3637,7 +3637,7 @@ msgstr "该日期无可用时段"
|
||||
|
||||
#: frontend/src/components/Modals/AnnouncementModal.vue:90
|
||||
msgid "No students in this batch"
|
||||
msgstr ""
|
||||
msgstr "本班级暂无学员"
|
||||
|
||||
#: frontend/src/pages/AssignmentSubmissionList.vue:67
|
||||
msgid "No submissions"
|
||||
@@ -4011,7 +4011,7 @@ msgstr "百分比/状态"
|
||||
#. Label of the persona_captured (Check) field in DocType 'LMS Settings'
|
||||
#: lms/lms/doctype/lms_settings/lms_settings.json
|
||||
msgid "Persona Captured"
|
||||
msgstr ""
|
||||
msgstr "用户画像已采集"
|
||||
|
||||
#: frontend/src/pages/Billing.vue:99
|
||||
msgid "Phone Number"
|
||||
@@ -4125,7 +4125,7 @@ msgstr "请选择时区"
|
||||
|
||||
#: frontend/src/components/Quiz.vue:497
|
||||
msgid "Please select an option"
|
||||
msgstr ""
|
||||
msgstr "请选择选项"
|
||||
|
||||
#: lms/templates/emails/job_report.html:6
|
||||
msgid "Please take appropriate action at {0}"
|
||||
@@ -4146,7 +4146,7 @@ msgstr "分数点(如70分)"
|
||||
|
||||
#: frontend/src/components/Modals/Question.vue:62
|
||||
msgid "Possibilities"
|
||||
msgstr ""
|
||||
msgstr "可能性分析"
|
||||
|
||||
#: frontend/src/components/Modals/Question.vue:88
|
||||
msgid "Possibility"
|
||||
@@ -4613,7 +4613,7 @@ msgstr "角色偏好"
|
||||
|
||||
#: frontend/src/pages/ProfileRoles.vue:105
|
||||
msgid "Role updated successfully"
|
||||
msgstr ""
|
||||
msgstr "角色更新成功。"
|
||||
|
||||
#: frontend/src/components/AppSidebar.vue:601
|
||||
msgid "Roles"
|
||||
@@ -4756,7 +4756,7 @@ msgstr "剩余席位"
|
||||
|
||||
#: lms/lms/doctype/lms_batch/lms_batch.py:103
|
||||
msgid "Seat count cannot be negative."
|
||||
msgstr ""
|
||||
msgstr "座位数不可为负数。"
|
||||
|
||||
#: frontend/src/components/BatchCard.vue:15
|
||||
#: frontend/src/components/BatchOverlay.vue:14
|
||||
@@ -4939,11 +4939,11 @@ msgstr "部分日程时段存在重叠"
|
||||
|
||||
#: frontend/src/pages/ProfileEvaluator.vue:201
|
||||
msgid "Slot added successfully"
|
||||
msgstr ""
|
||||
msgstr "时段添加成功。"
|
||||
|
||||
#: frontend/src/pages/ProfileEvaluator.vue:240
|
||||
msgid "Slot deleted successfully"
|
||||
msgstr ""
|
||||
msgstr "时段删除成功。"
|
||||
|
||||
#. Label of the slug (Data) field in DocType 'Cohort'
|
||||
#. Label of the slug (Data) field in DocType 'Cohort Subgroup'
|
||||
@@ -5139,7 +5139,7 @@ msgstr "主题"
|
||||
|
||||
#: frontend/src/components/Modals/AnnouncementModal.vue:93
|
||||
msgid "Subject is required"
|
||||
msgstr ""
|
||||
msgstr "必须填写主题"
|
||||
|
||||
#: frontend/src/components/Assignment.vue:32
|
||||
msgid "Submission"
|
||||
@@ -5172,7 +5172,7 @@ msgstr "提交"
|
||||
|
||||
#: frontend/src/pages/PersonaForm.vue:43
|
||||
msgid "Submit and Continue"
|
||||
msgstr ""
|
||||
msgstr "提交并继续"
|
||||
|
||||
#: 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."
|
||||
@@ -5364,7 +5364,7 @@ msgstr "本作业暂无提交记录"
|
||||
|
||||
#: frontend/src/components/EmptyState.vue:11
|
||||
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
|
||||
msgid "There are no {0} on this site."
|
||||
@@ -5415,11 +5415,11 @@ msgstr "本描述将展示在无元描述的列表及页面中"
|
||||
#. Settings'
|
||||
#: 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"
|
||||
msgstr ""
|
||||
msgstr "本图片将显示在无默认图片的列表及页面"
|
||||
|
||||
#: frontend/src/pages/Lesson.vue:24
|
||||
msgid "This lesson is locked"
|
||||
msgstr ""
|
||||
msgstr "本课时已锁定"
|
||||
|
||||
#: frontend/src/pages/Lesson.vue:29
|
||||
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:115
|
||||
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 'LMS Certificate Request'
|
||||
@@ -5648,7 +5648,7 @@ msgstr "不可用状态"
|
||||
|
||||
#: frontend/src/pages/ProfileEvaluator.vue:259
|
||||
msgid "Unavailability updated successfully"
|
||||
msgstr ""
|
||||
msgstr "不可用状态更新成功"
|
||||
|
||||
#: lms/lms/doctype/course_evaluator/course_evaluator.py:29
|
||||
msgid "Unavailable From Date cannot be greater than Unavailable To Date"
|
||||
@@ -5856,7 +5856,7 @@ msgstr "网页"
|
||||
|
||||
#: frontend/src/components/Modals/PageModal.vue:80
|
||||
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 'LMS Certificate Request'
|
||||
@@ -5872,7 +5872,7 @@ msgstr "欢迎使用{0}!"
|
||||
|
||||
#: frontend/src/pages/PersonaForm.vue:32
|
||||
msgid "What best describes your role?"
|
||||
msgstr ""
|
||||
msgstr "请选择最能描述您角色的选项"
|
||||
|
||||
#: frontend/src/components/LessonHelp.vue:6
|
||||
msgid "What does include in preview mean?"
|
||||
@@ -5880,7 +5880,7 @@ msgstr "「包含在预览中」的含义是什么?"
|
||||
|
||||
#: frontend/src/pages/PersonaForm.vue:21
|
||||
msgid "What is your use case for Frappe Learning?"
|
||||
msgstr ""
|
||||
msgstr "您使用Frappe Learning的主要场景是?"
|
||||
|
||||
#: lms/templates/courses_under_review.html:15
|
||||
msgid "When a course gets submitted for review, it will be listed here."
|
||||
@@ -5978,11 +5978,11 @@ msgstr "简历已作为附件发送至本邮箱"
|
||||
|
||||
#: frontend/src/pages/ProfileEvaluator.vue:14
|
||||
msgid "You cannot change the availability when the site is being updated."
|
||||
msgstr ""
|
||||
msgstr "系统更新期间不可修改可用性设置。"
|
||||
|
||||
#: frontend/src/pages/ProfileRoles.vue:12
|
||||
msgid "You cannot change the roles in read-only mode."
|
||||
msgstr ""
|
||||
msgstr "只读模式下不可修改角色。"
|
||||
|
||||
#: lms/lms/doctype/lms_certificate_request/lms_certificate_request.py:116
|
||||
msgid "You cannot schedule evaluations after {0}."
|
||||
@@ -6031,7 +6031,7 @@ msgstr "您已评价过本课程"
|
||||
|
||||
#: frontend/src/pages/JobDetail.vue:57
|
||||
msgid "You have applied"
|
||||
msgstr ""
|
||||
msgstr "您已申请"
|
||||
|
||||
#: frontend/src/components/BatchOverlay.vue:159
|
||||
msgid "You have been enrolled in this batch"
|
||||
@@ -6124,7 +6124,7 @@ msgstr "提交内容已保存,讲师将尽快评阅并通知最终结果"
|
||||
|
||||
#: frontend/src/pages/Lesson.vue:8
|
||||
msgid "Zen Mode"
|
||||
msgstr ""
|
||||
msgstr "禅模式"
|
||||
|
||||
#. Name of a DocType
|
||||
#: 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
|
||||
msgid "applicant"
|
||||
msgstr ""
|
||||
msgstr "申请人"
|
||||
|
||||
#: frontend/src/components/JobCard.vue:26 frontend/src/pages/JobDetail.vue:108
|
||||
msgid "applicants"
|
||||
msgstr ""
|
||||
msgstr "申请人列表"
|
||||
|
||||
#: lms/templates/emails/payment_reminder.html:4
|
||||
msgid "but didn’t complete your payment"
|
||||
@@ -6225,15 +6225,15 @@ msgstr "您可以"
|
||||
|
||||
#: frontend/src/pages/Assignments.vue:29
|
||||
msgid "{0} Assignments"
|
||||
msgstr ""
|
||||
msgstr "{0}项作业"
|
||||
|
||||
#: frontend/src/pages/Jobs.vue:33
|
||||
msgid "{0} Open Jobs"
|
||||
msgstr ""
|
||||
msgstr "{0}个开放职位"
|
||||
|
||||
#: frontend/src/pages/Quizzes.vue:25
|
||||
msgid "{0} Quizzes"
|
||||
msgstr ""
|
||||
msgstr "{0}项测验"
|
||||
|
||||
#: lms/lms/api.py:853 lms/lms/api.py:861
|
||||
msgid "{0} Settings not found"
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
"homepage": "https://github.com/frappe/lms#readme",
|
||||
"devDependencies": {
|
||||
"cypress": "^13.9.0",
|
||||
"cypress-file-upload": "^5.0.8"
|
||||
"cypress-file-upload": "^5.0.8",
|
||||
"cypress-real-events": "^1.14.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"pre-commit": "^1.2.2"
|
||||
|
||||
@@ -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"
|
||||
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:
|
||||
version "13.17.0"
|
||||
resolved "https://registry.yarnpkg.com/cypress/-/cypress-13.17.0.tgz#34c3d68080c4497eace0f353bd1629587a5f600d"
|
||||
|
||||
Reference in New Issue
Block a user