Merge pull request #1396 from pateljannat/assignment-in-course-issue
fix: assignment and quiz rendering issue in courses
This commit is contained in:
1
frontend/components.d.ts
vendored
1
frontend/components.d.ts
vendored
@@ -66,6 +66,7 @@ declare module 'vue' {
|
|||||||
MobileLayout: typeof import('./src/components/MobileLayout.vue')['default']
|
MobileLayout: typeof import('./src/components/MobileLayout.vue')['default']
|
||||||
MultiSelect: typeof import('./src/components/Controls/MultiSelect.vue')['default']
|
MultiSelect: typeof import('./src/components/Controls/MultiSelect.vue')['default']
|
||||||
NoPermission: typeof import('./src/components/NoPermission.vue')['default']
|
NoPermission: typeof import('./src/components/NoPermission.vue')['default']
|
||||||
|
NoSidebarLayout: typeof import('./src/components/NoSidebarLayout.vue')['default']
|
||||||
NotPermitted: typeof import('./src/components/NotPermitted.vue')['default']
|
NotPermitted: typeof import('./src/components/NotPermitted.vue')['default']
|
||||||
OnboardingBanner: typeof import('./src/components/OnboardingBanner.vue')['default']
|
OnboardingBanner: typeof import('./src/components/OnboardingBanner.vue')['default']
|
||||||
PageModal: typeof import('./src/components/Modals/PageModal.vue')['default']
|
PageModal: typeof import('./src/components/Modals/PageModal.vue')['default']
|
||||||
|
|||||||
@@ -8,18 +8,34 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Toasts } from 'frappe-ui'
|
import { Toasts } from 'frappe-ui'
|
||||||
import { Dialogs } from '@/utils/dialogs'
|
import { Dialogs } from '@/utils/dialogs'
|
||||||
import { computed, onMounted, onUnmounted } from 'vue'
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
import { useScreenSize } from './utils/composables'
|
import { useScreenSize } from './utils/composables'
|
||||||
import DesktopLayout from './components/DesktopLayout.vue'
|
import DesktopLayout from './components/DesktopLayout.vue'
|
||||||
import MobileLayout from './components/MobileLayout.vue'
|
import MobileLayout from './components/MobileLayout.vue'
|
||||||
|
import NoSidebarLayout from './components/NoSidebarLayout.vue'
|
||||||
import { stopSession } from '@/telemetry'
|
import { stopSession } from '@/telemetry'
|
||||||
import { init as initTelemetry } from '@/telemetry'
|
import { init as initTelemetry } from '@/telemetry'
|
||||||
import { usersStore } from '@/stores/user'
|
import { usersStore } from '@/stores/user'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
const screenSize = useScreenSize()
|
const screenSize = useScreenSize()
|
||||||
let { userResource } = usersStore()
|
let { userResource } = usersStore()
|
||||||
|
const router = useRouter()
|
||||||
|
const noSidebar = ref(false)
|
||||||
|
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
if (to.query.fromLesson) {
|
||||||
|
noSidebar.value = true
|
||||||
|
} else {
|
||||||
|
noSidebar.value = false
|
||||||
|
}
|
||||||
|
next()
|
||||||
|
})
|
||||||
|
|
||||||
const Layout = computed(() => {
|
const Layout = computed(() => {
|
||||||
|
if (noSidebar.value) {
|
||||||
|
return NoSidebarLayout
|
||||||
|
}
|
||||||
if (screenSize.width < 640) {
|
if (screenSize.width < 640) {
|
||||||
return MobileLayout
|
return MobileLayout
|
||||||
} else {
|
} else {
|
||||||
@@ -28,11 +44,11 @@ const Layout = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
if (!userResource.data) return
|
if (userResource.data) await initTelemetry()
|
||||||
await initTelemetry()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
noSidebar.value = false
|
||||||
stopSession()
|
stopSession()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -188,7 +188,12 @@ const addQuizzes = () => {
|
|||||||
label: 'Quizzes',
|
label: 'Quizzes',
|
||||||
icon: 'CircleHelp',
|
icon: 'CircleHelp',
|
||||||
to: 'Quizzes',
|
to: 'Quizzes',
|
||||||
activeFor: ['Quizzes', 'QuizForm'],
|
activeFor: [
|
||||||
|
'Quizzes',
|
||||||
|
'QuizForm',
|
||||||
|
'QuizSubmissionList',
|
||||||
|
'QuizSubmission',
|
||||||
|
],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,7 +204,12 @@ const addAssignments = () => {
|
|||||||
label: 'Assignments',
|
label: 'Assignments',
|
||||||
icon: 'Pencil',
|
icon: 'Pencil',
|
||||||
to: 'Assignments',
|
to: 'Assignments',
|
||||||
activeFor: ['Assignments', 'AssignmentForm'],
|
activeFor: [
|
||||||
|
'Assignments',
|
||||||
|
'AssignmentForm',
|
||||||
|
'AssignmentSubmissionList',
|
||||||
|
'AssignmentSubmission',
|
||||||
|
],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-if="assignment.data"
|
v-if="assignment.data"
|
||||||
class="grid grid-cols-[60%,40%] h-full"
|
class="grid grid-cols-2 h-full"
|
||||||
:class="{ 'border rounded-lg': !showTitle }"
|
:class="{ 'border rounded-lg overflow-auto': !showTitle }"
|
||||||
>
|
>
|
||||||
<div class="border-r p-5 overflow-y-auto h-[calc(100vh-3.2rem)]">
|
<div
|
||||||
|
class="border-r p-5 overflow-y-auto h-[calc(100vh-3.2rem)]"
|
||||||
|
:class="{ 'h-full': !showTitle }"
|
||||||
|
>
|
||||||
<div v-if="showTitle" class="text-lg font-semibold mb-5 text-ink-gray-9">
|
<div v-if="showTitle" class="text-lg font-semibold mb-5 text-ink-gray-9">
|
||||||
<div v-if="submissionName === 'new'">
|
<div v-if="submissionName === 'new'">
|
||||||
{{ __('Submission by') }} {{ user.data?.full_name }}
|
{{ __('Submission by') }} {{ user.data?.full_name }}
|
||||||
@@ -50,7 +53,7 @@
|
|||||||
!['Pass', 'Fail'].includes(submissionResource.doc?.status) &&
|
!['Pass', 'Fail'].includes(submissionResource.doc?.status) &&
|
||||||
submissionResource.doc?.owner == user.data?.name
|
submissionResource.doc?.owner == user.data?.name
|
||||||
"
|
"
|
||||||
class="bg-surface-blue-2 p-3 rounded-md leading-5 text-sm mb-4"
|
class="bg-surface-blue-2 text-ink-blue-2 p-3 rounded-md leading-5 text-sm mb-4"
|
||||||
>
|
>
|
||||||
{{ __("You've successfully submitted the assignment.") }}
|
{{ __("You've successfully submitted the assignment.") }}
|
||||||
{{
|
{{
|
||||||
@@ -115,14 +118,8 @@
|
|||||||
:readonly="!canModifyAssignment"
|
:readonly="!canModifyAssignment"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="true">
|
<div v-else>
|
||||||
<div class="text-sm mb-4">
|
<div class="text-sm mb-2 text-ink-gray-7">
|
||||||
{{ __('Write your answer here') }}
|
|
||||||
</div>
|
|
||||||
<FormControl />
|
|
||||||
</div>
|
|
||||||
<!-- <div v-else>
|
|
||||||
<div class="text-sm mb-4">
|
|
||||||
{{ __('Write your answer here') }}
|
{{ __('Write your answer here') }}
|
||||||
</div>
|
</div>
|
||||||
<TextEditor
|
<TextEditor
|
||||||
@@ -132,7 +129,7 @@
|
|||||||
:fixedMenu="true"
|
:fixedMenu="true"
|
||||||
editorClass="prose-sm max-w-none border-b border-x bg-surface-gray-2 rounded-b-md py-1 px-2 min-h-[7rem]"
|
editorClass="prose-sm max-w-none border-b border-x bg-surface-gray-2 rounded-b-md py-1 px-2 min-h-[7rem]"
|
||||||
/>
|
/>
|
||||||
</div> -->
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="
|
v-if="
|
||||||
@@ -144,9 +141,10 @@
|
|||||||
<div class="text-sm text-ink-gray-5 font-medium mb-2">
|
<div class="text-sm text-ink-gray-5 font-medium mb-2">
|
||||||
{{ __('Comments by Evaluator') }}:
|
{{ __('Comments by Evaluator') }}:
|
||||||
</div>
|
</div>
|
||||||
<div class="leading-5">
|
<div
|
||||||
{{ submissionResource.doc.comments }}
|
class="leading-5 text-ink-gray-9"
|
||||||
</div>
|
v-html="submissionResource.doc.comments"
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Grading -->
|
<!-- Grading -->
|
||||||
@@ -204,7 +202,6 @@ const answer = ref(null)
|
|||||||
const comments = ref(null)
|
const comments = ref(null)
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const user = inject('$user')
|
const user = inject('$user')
|
||||||
const showTitle = router.currentRoute.value.name == 'AssignmentSubmission'
|
|
||||||
const isDirty = ref(false)
|
const isDirty = ref(false)
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -216,6 +213,10 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: 'new',
|
default: 'new',
|
||||||
},
|
},
|
||||||
|
showTitle: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -359,6 +360,7 @@ const addNewSubmission = () => {
|
|||||||
assignmentID: props.assignmentID,
|
assignmentID: props.assignmentID,
|
||||||
submissionName: data.name,
|
submissionName: data.name,
|
||||||
},
|
},
|
||||||
|
query: { fromLesson: router.currentRoute.value.query.fromLesson },
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
markLessonProgress()
|
markLessonProgress()
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
<template>
|
|
||||||
<Assignment
|
|
||||||
v-if="user.data && submission.data"
|
|
||||||
:assignmentID="assignmentID"
|
|
||||||
:submissionName="submission.data?.name || 'new'"
|
|
||||||
/>
|
|
||||||
<div v-else class="border rounded-md text-center py-20">
|
|
||||||
<div>
|
|
||||||
{{ __('Please login to access the assignment.') }}
|
|
||||||
</div>
|
|
||||||
<Button @click="redirectToLogin()" class="mt-2">
|
|
||||||
<span>
|
|
||||||
{{ __('Login') }}
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script setup>
|
|
||||||
import { inject } from 'vue'
|
|
||||||
import { Button, createResource } from 'frappe-ui'
|
|
||||||
import Assignment from '@/components/Assignment.vue'
|
|
||||||
|
|
||||||
const user = inject('$user')
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
assignmentID: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const submission = createResource({
|
|
||||||
url: 'frappe.client.get_value',
|
|
||||||
makeParams(values) {
|
|
||||||
return {
|
|
||||||
doctype: 'LMS Assignment Submission',
|
|
||||||
fieldname: 'name',
|
|
||||||
filters: {
|
|
||||||
assignment: props.assignmentID,
|
|
||||||
member: user.data?.name,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
auto: true,
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
<div
|
<div
|
||||||
class="outline-lesson pl-8 py-2 pr-4 text-ink-gray-9"
|
class="outline-lesson pl-8 py-2 pr-4 text-ink-gray-9"
|
||||||
:class="
|
:class="
|
||||||
isActiveLesson(lesson.number) ? 'bg-surface-selected' : ''
|
isActiveLesson(lesson.number) ? 'bg-surface-gray-3' : ''
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
|
|||||||
11
frontend/src/components/NoSidebarLayout.vue
Normal file
11
frontend/src/components/NoSidebarLayout.vue
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<div class="relative flex h-full flex-col">
|
||||||
|
<div class="h-full flex-1">
|
||||||
|
<div class="flex h-screen text-base bg-surface-white">
|
||||||
|
<div class="w-full overflow-auto" id="scrollContainer">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="quiz.data">
|
<div v-if="quiz.data">
|
||||||
<div
|
<div
|
||||||
class="bg-surface-blue-2 space-y-1 py-2 px-2 mb-4 rounded-md text-sm text-ink-blue-800"
|
class="bg-surface-blue-2 space-y-1 py-2 px-2 mb-4 rounded-md text-sm text-ink-blue-2"
|
||||||
>
|
>
|
||||||
<div class="leading-5">
|
<div class="leading-5">
|
||||||
{{
|
{{
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
).format(quiz.data.passing_percentage)
|
).format(quiz.data.passing_percentage)
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="quiz.data.max_attempts" class="leading-relaxed">
|
<div v-if="quiz.data.max_attempts" class="leading-5">
|
||||||
{{
|
{{
|
||||||
__('You can attempt this quiz {0}.').format(
|
__('You can attempt this quiz {0}.').format(
|
||||||
quiz.data.max_attempts == 1
|
quiz.data.max_attempts == 1
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
<div v-if="activeQuestion == 0">
|
<div v-if="activeQuestion == 0">
|
||||||
<div class="border text-center p-20 rounded-md">
|
<div class="border text-center p-20 rounded-md">
|
||||||
<div class="font-semibold text-lg">
|
<div class="font-semibold text-lg text-ink-gray-9">
|
||||||
{{ quiz.data.title }}
|
{{ quiz.data.title }}
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
{{ __('Start') }}
|
{{ __('Start') }}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
<div v-else>
|
<div v-else class="leading-5 text-ink-gray-7">
|
||||||
{{
|
{{
|
||||||
__(
|
__(
|
||||||
'You have already exceeded the maximum number of attempts allowed for this quiz.'
|
'You have already exceeded the maximum number of attempts allowed for this quiz.'
|
||||||
@@ -222,11 +222,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="border rounded-md p-20 text-center space-y-4">
|
<div v-else class="border rounded-md p-20 text-center space-y-2">
|
||||||
<div class="text-lg font-semibold">
|
<div class="text-lg font-semibold text-ink-gray-9">
|
||||||
{{ __('Quiz Summary') }}
|
{{ __('Quiz Summary') }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="quizSubmission.data.is_open_ended">
|
<div
|
||||||
|
v-if="quizSubmission.data.is_open_ended"
|
||||||
|
class="leading-5 text-ink-gray-7"
|
||||||
|
>
|
||||||
{{
|
{{
|
||||||
__(
|
__(
|
||||||
"Your submission has been successfully saved. The instructor will review and grade it shortly, and you'll be notified of your final result."
|
"Your submission has been successfully saved. The instructor will review and grade it shortly, and you'll be notified of your final result."
|
||||||
@@ -613,7 +616,6 @@ const getInstructions = (question) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const markLessonProgress = () => {
|
const markLessonProgress = () => {
|
||||||
console.log(router)
|
|
||||||
if (router.currentRoute.value.name == 'Lesson') {
|
if (router.currentRoute.value.name == 'Lesson') {
|
||||||
call('lms.lms.api.mark_lesson_progress', {
|
call('lms.lms.api.mark_lesson_progress', {
|
||||||
course: router.currentRoute.value.params.courseName,
|
course: router.currentRoute.value.params.courseName,
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
<button
|
<button
|
||||||
v-if="link && !link.onlyMobile"
|
v-if="link && !link.onlyMobile"
|
||||||
class="flex h-7 cursor-pointer items-center rounded text-ink-gray-8 duration-300 ease-in-out focus:outline-none focus:transition-none focus-visible:rounded focus-visible:ring-2 focus-visible:ring-outline-gray-3"
|
class="flex h-7 cursor-pointer items-center rounded text-ink-gray-8 duration-300 ease-in-out focus:outline-none focus:transition-none focus-visible:rounded focus-visible:ring-2 focus-visible:ring-outline-gray-3"
|
||||||
:class="isActive ? 'bg-surface-white shadow-sm' : 'hover:bg-surface-gray-2'"
|
:class="
|
||||||
|
isActive ? 'bg-surface-selected shadow-sm' : 'hover:bg-surface-gray-2'
|
||||||
|
"
|
||||||
@click="handleClick"
|
@click="handleClick"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,19 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<header
|
<header
|
||||||
|
v-if="!fromLesson"
|
||||||
class="flex justify-between sticky top-0 z-10 border-b bg-surface-white px-3 py-2.5 sm:px-5"
|
class="flex justify-between sticky top-0 z-10 border-b bg-surface-white px-3 py-2.5 sm:px-5"
|
||||||
>
|
>
|
||||||
<Breadcrumbs :items="breadcrumbs" />
|
<Breadcrumbs :items="breadcrumbs" />
|
||||||
</header>
|
</header>
|
||||||
<div class="overflow-hidden h-[calc(100vh-3.2rem)]">
|
<div class="overflow-hidden h-[calc(100vh-3.2rem)]">
|
||||||
<Assignment :assignmentID="assignmentID" :submissionName="submissionName" />
|
<Assignment
|
||||||
|
:assignmentID="assignmentID"
|
||||||
|
:submissionName="submissionName"
|
||||||
|
:showTitle="!fromLesson"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Breadcrumbs, createResource } from 'frappe-ui'
|
import { Breadcrumbs, createResource } from 'frappe-ui'
|
||||||
import { computed, inject, onMounted } from 'vue'
|
import { computed, inject, onMounted, onBeforeUnmount, ref } from 'vue'
|
||||||
import Assignment from '@/components/Assignment.vue'
|
import Assignment from '@/components/Assignment.vue'
|
||||||
|
|
||||||
const user = inject('$user')
|
const user = inject('$user')
|
||||||
|
const fromLesson = ref(false)
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
assignmentID: {
|
assignmentID: {
|
||||||
@@ -42,6 +48,10 @@ onMounted(() => {
|
|||||||
if (!user.data) {
|
if (!user.data) {
|
||||||
window.location.href = '/login'
|
window.location.href = '/login'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (new URLSearchParams(window.location.search).get('fromLesson')) {
|
||||||
|
fromLesson.value = true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const breadcrumbs = computed(() => {
|
const breadcrumbs = computed(() => {
|
||||||
|
|||||||
@@ -587,11 +587,6 @@ updateDocumentTitle(pageMeta)
|
|||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
iframe {
|
|
||||||
border-top: 3px solid theme('colors.gray.700');
|
|
||||||
border-bottom: 3px solid theme('colors.gray.700');
|
|
||||||
}
|
|
||||||
|
|
||||||
.tc-table {
|
.tc-table {
|
||||||
border-left: 1px solid #e8e8eb;
|
border-left: 1px solid #e8e8eb;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,36 @@
|
|||||||
<template>
|
<template>
|
||||||
<header
|
<header
|
||||||
|
v-if="!fromLesson"
|
||||||
class="sticky top-0 z-10 flex items-center justify-between border-b bg-surface-white px-3 py-2.5 sm:px-5"
|
class="sticky top-0 z-10 flex items-center justify-between border-b bg-surface-white px-3 py-2.5 sm:px-5"
|
||||||
>
|
>
|
||||||
<Breadcrumbs :items="breadcrumbs" />
|
<Breadcrumbs :items="breadcrumbs" />
|
||||||
</header>
|
</header>
|
||||||
<div class="md:w-7/12 md:mx-auto mx-4 py-10">
|
<div
|
||||||
|
class="md:w-7/12 md:mx-auto mx-4 py-10"
|
||||||
|
:class="{ 'pt-4 md:w-full': fromLesson }"
|
||||||
|
>
|
||||||
<Quiz :quizName="quizID" />
|
<Quiz :quizName="quizID" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import Quiz from '@/components/Quiz.vue'
|
import Quiz from '@/components/Quiz.vue'
|
||||||
import { createResource, Breadcrumbs } from 'frappe-ui'
|
import { createResource, Breadcrumbs } from 'frappe-ui'
|
||||||
import { computed, inject, onMounted } from 'vue'
|
import { computed, inject, onMounted, ref } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { updateDocumentTitle } from '@/utils'
|
import { updateDocumentTitle } from '@/utils'
|
||||||
|
|
||||||
const user = inject('$user')
|
const user = inject('$user')
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const fromLesson = ref(false)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (!user.data) {
|
if (!user.data) {
|
||||||
router.push({ name: 'Courses' })
|
router.push({ name: 'Courses' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (new URLSearchParams(window.location.search).get('fromLesson')) {
|
||||||
|
fromLesson.value = true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import { Pencil } from 'lucide-vue-next'
|
import { Pencil } from 'lucide-vue-next'
|
||||||
import { createApp, h } from 'vue'
|
import { createApp, h } from 'vue'
|
||||||
import AssessmentPlugin from '@/components/AssessmentPlugin.vue'
|
import AssessmentPlugin from '@/components/AssessmentPlugin.vue'
|
||||||
import AssignmentBlock from '@/components/AssignmentBlock.vue'
|
|
||||||
import translationPlugin from '../translation'
|
import translationPlugin from '../translation'
|
||||||
import { usersStore } from '@/stores/user'
|
import { usersStore } from '@/stores/user'
|
||||||
import router from '../router'
|
import { call } from 'frappe-ui'
|
||||||
import { FrappeUI, setConfig, frappeRequest, pageMetaPlugin } from 'frappe-ui'
|
|
||||||
|
|
||||||
export class Assignment {
|
export class Assignment {
|
||||||
constructor({ data, api, readOnly }) {
|
constructor({ data, api, readOnly }) {
|
||||||
@@ -44,17 +42,18 @@ export class Assignment {
|
|||||||
|
|
||||||
renderAssignment(assignment) {
|
renderAssignment(assignment) {
|
||||||
if (this.readOnly) {
|
if (this.readOnly) {
|
||||||
const app = createApp(AssignmentBlock, {
|
|
||||||
assignmentID: assignment,
|
|
||||||
})
|
|
||||||
app.use(FrappeUI)
|
|
||||||
setConfig('resourceFetcher', frappeRequest)
|
|
||||||
app.use(translationPlugin)
|
|
||||||
app.use(router)
|
|
||||||
app.use(pageMetaPlugin)
|
|
||||||
const { userResource } = usersStore()
|
const { userResource } = usersStore()
|
||||||
app.provide('$user', userResource)
|
call('frappe.client.get_value', {
|
||||||
app.mount(this.wrapper)
|
doctype: 'LMS Assignment Submission',
|
||||||
|
filters: {
|
||||||
|
assignment: assignment,
|
||||||
|
member: userResource.data?.name,
|
||||||
|
},
|
||||||
|
fieldname: ['name'],
|
||||||
|
}).then((data) => {
|
||||||
|
let submission = data.name || 'new'
|
||||||
|
this.wrapper.innerHTML = `<iframe src="/lms/assignment-submission/${assignment}/${submission}?fromLesson=1" class="w-full h-[500px]"></iframe>`
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.wrapper.innerHTML = `<div class='border rounded-md p-10 text-center bg-surface-menu-bar mb-2'>
|
this.wrapper.innerHTML = `<div class='border rounded-md p-10 text-center bg-surface-menu-bar mb-2'>
|
||||||
|
|||||||
@@ -43,14 +43,7 @@ export class Quiz {
|
|||||||
|
|
||||||
renderQuiz(quiz) {
|
renderQuiz(quiz) {
|
||||||
if (this.readOnly) {
|
if (this.readOnly) {
|
||||||
const app = createApp(QuizBlock, {
|
this.wrapper.innerHTML = `<iframe src="/lms/quiz/${quiz}?fromLesson=1" class="w-full h-[500px]"></iframe>`
|
||||||
quiz: quiz,
|
|
||||||
})
|
|
||||||
app.use(translationPlugin)
|
|
||||||
app.use(router)
|
|
||||||
const { userResource } = usersStore()
|
|
||||||
app.provide('$user', userResource)
|
|
||||||
app.mount(this.wrapper)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.wrapper.innerHTML = `<div class='border rounded-md p-10 text-center bg-surface-menu-bar mb-2'>
|
this.wrapper.innerHTML = `<div class='border rounded-md p-10 text-center bg-surface-menu-bar mb-2'>
|
||||||
|
|||||||
@@ -56,11 +56,11 @@ export class Upload {
|
|||||||
app.mount(this.wrapper)
|
app.mount(this.wrapper)
|
||||||
return
|
return
|
||||||
} else if (file.file_type == 'PDF') {
|
} else if (file.file_type == 'PDF') {
|
||||||
this.wrapper.innerHTML = `<iframe src="https://docs.google.com/viewer?url=${
|
this.wrapper.innerHTML = `<iframe src="${
|
||||||
window.location.origin
|
window.location.origin
|
||||||
}${encodeURI(
|
}${encodeURI(
|
||||||
file.file_url
|
file.file_url
|
||||||
)}&embedded=true" width='100%' height='700px' class="mb-4" type="application/pdf"></iframe>`
|
)}" width='100%' height='700px' class="mb-4" type="application/pdf"></iframe>`
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
this.wrapper.innerHTML = `<img class="mb-4" src=${encodeURI(
|
this.wrapper.innerHTML = `<img class="mb-4" src=${encodeURI(
|
||||||
|
|||||||
Reference in New Issue
Block a user