feat: allow updating questions
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,4 +12,3 @@ node_modules
|
|||||||
package-lock.json
|
package-lock.json
|
||||||
lms/public/frontend
|
lms/public/frontend
|
||||||
lms/www/lms.html
|
lms/www/lms.html
|
||||||
frappe-ui
|
|
||||||
Submodule frappe-ui deleted from a349ab070a
@@ -2,7 +2,7 @@
|
|||||||
<Dialog v-model="show" :options="dialogOptions">
|
<Dialog v-model="show" :options="dialogOptions">
|
||||||
<template #body-content>
|
<template #body-content>
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div class="flex items-center text-xs text-gray-700 space-x-5">
|
<div v-if="!editMode" class="flex items-center text-xs text-gray-700 space-x-5">
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="questionType == 'new'" class="space-y-2">
|
<div v-if="questionType == 'new' || editMode" class="space-y-2">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-xs text-gray-600 mb-1">
|
<label class="block text-xs text-gray-600 mb-1">
|
||||||
{{ __('Question') }}
|
{{ __('Question') }}
|
||||||
@@ -100,7 +100,6 @@ import {
|
|||||||
FormControl,
|
FormControl,
|
||||||
TextEditor,
|
TextEditor,
|
||||||
createResource,
|
createResource,
|
||||||
createDocumentResource,
|
|
||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
import { computed, watch, reactive, ref } from 'vue'
|
import { computed, watch, reactive, ref } from 'vue'
|
||||||
import Link from '@/components/Controls/Link.vue'
|
import Link from '@/components/Controls/Link.vue'
|
||||||
@@ -109,6 +108,8 @@ import { showToast } from '@/utils'
|
|||||||
const show = defineModel()
|
const show = defineModel()
|
||||||
const quiz = defineModel('quiz')
|
const quiz = defineModel('quiz')
|
||||||
const questionType = ref(null)
|
const questionType = ref(null)
|
||||||
|
const editMode = ref(false)
|
||||||
|
|
||||||
const existingQuestion = reactive({
|
const existingQuestion = reactive({
|
||||||
question: '',
|
question: '',
|
||||||
marks: 0,
|
marks: 0,
|
||||||
@@ -137,25 +138,39 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: __('Add a new question'),
|
default: __('Add a new question'),
|
||||||
},
|
},
|
||||||
questionData: {
|
questionName: {
|
||||||
type: [Object, null],
|
type: [String, null],
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(show, () => {
|
const questionData = createResource({
|
||||||
let data = props.questionData
|
url: 'frappe.client.get',
|
||||||
if (show.value && data) {
|
makeParams() {
|
||||||
|
return {
|
||||||
|
doctype: 'LMS Question',
|
||||||
|
name: props.questionName,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
auto: false,
|
||||||
|
cache: ['question', props.questionName],
|
||||||
|
onSuccess(data) {
|
||||||
let counter = 1
|
let counter = 1
|
||||||
|
editMode.value = true
|
||||||
Object.keys(data).forEach((key) => {
|
Object.keys(data).forEach((key) => {
|
||||||
if (Object.hasOwn(question, key)) question[key] = data[key]
|
if (Object.hasOwn(question, key)) question[key] = data[key]
|
||||||
})
|
})
|
||||||
while (counter <= 4) {
|
while (counter <= 4) {
|
||||||
question[`is_correct_${counter}`] = question[`is_correct_${counter}`]
|
question[`is_correct_${counter}`] = data[`is_correct_${counter}`]
|
||||||
? true
|
? true
|
||||||
: false
|
: false
|
||||||
|
counter++;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(show, () => {
|
||||||
|
if (show.value && props.questionName) questionData.fetch()
|
||||||
})
|
})
|
||||||
|
|
||||||
const questionRow = createResource({
|
const questionRow = createResource({
|
||||||
@@ -187,7 +202,7 @@ const questionCreation = createResource({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const submitQuestion = (close) => {
|
const submitQuestion = (close) => {
|
||||||
if (questionData.data?.name) updateQuestion()
|
if (questionData.data?.name) updateQuestion(close)
|
||||||
else addQuestion(close)
|
else addQuestion(close)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,6 +256,38 @@ const addQuestionRow = (question, close) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const questionUpdate = createResource({
|
||||||
|
url: 'frappe.client.set_value',
|
||||||
|
auto: false,
|
||||||
|
makeParams(values) {
|
||||||
|
return {
|
||||||
|
doctype: 'LMS Question',
|
||||||
|
name: questionData.data?.name,
|
||||||
|
fieldname: {
|
||||||
|
...question,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const updateQuestion = (close) => {
|
||||||
|
questionUpdate.submit(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
onSuccess() {
|
||||||
|
show.value = false
|
||||||
|
showToast(__('Success'), __('Question updated successfully'), 'check')
|
||||||
|
quiz.value.reload()
|
||||||
|
close()
|
||||||
|
},
|
||||||
|
onError(err) {
|
||||||
|
showToast(__('Error'), __(err.message?.[0] || err), 'x')
|
||||||
|
close()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const dialogOptions = computed(() => {
|
const dialogOptions = computed(() => {
|
||||||
return {
|
return {
|
||||||
title: __(props.title),
|
title: __(props.title),
|
||||||
|
|||||||
@@ -123,7 +123,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<Question
|
<Question
|
||||||
v-model="showQuestionModal"
|
v-model="showQuestionModal"
|
||||||
:questionData="currentQuestion"
|
:questionName="currentQuestion"
|
||||||
v-model:quiz="quizDetails"
|
v-model:quiz="quizDetails"
|
||||||
:title="
|
:title="
|
||||||
currentQuestion ? __('Edit the question') : __('Add a new question')
|
currentQuestion ? __('Edit the question') : __('Add a new question')
|
||||||
@@ -172,7 +172,6 @@ onMounted(() => {
|
|||||||
router.push({ name: 'Courses' })
|
router.push({ name: 'Courses' })
|
||||||
}
|
}
|
||||||
if (props.quizID !== 'new') {
|
if (props.quizID !== 'new') {
|
||||||
console.log('here')
|
|
||||||
quizDetails.reload()
|
quizDetails.reload()
|
||||||
}
|
}
|
||||||
window.addEventListener('keydown', keyboardShortcut)
|
window.addEventListener('keydown', keyboardShortcut)
|
||||||
@@ -343,32 +342,9 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const questionData = createResource({
|
|
||||||
url: 'lms.lms.utils.get_question_details',
|
|
||||||
makeParams(values) {
|
|
||||||
return {
|
|
||||||
question: values.question,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
auto: false,
|
|
||||||
cache: ['question', props.questionName],
|
|
||||||
})
|
|
||||||
|
|
||||||
const openQuestionModal = (question = null) => {
|
const openQuestionModal = (question = null) => {
|
||||||
if (question) {
|
currentQuestion.value = question
|
||||||
questionData.reload(
|
showQuestionModal.value = true
|
||||||
{ question },
|
|
||||||
{
|
|
||||||
onSuccess(data) {
|
|
||||||
currentQuestion.value = data
|
|
||||||
showQuestionModal.value = true
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
currentQuestion.value = null
|
|
||||||
showQuestionModal.value = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const breadcrumbs = computed(() => {
|
const breadcrumbs = computed(() => {
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ class LMSQuestion(Document):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
validate_correct_answers(self)
|
validate_correct_answers(self)
|
||||||
|
|
||||||
|
|
||||||
def validate_correct_answers(question):
|
def validate_correct_answers(question):
|
||||||
if question.type == "Choices":
|
if question.type == "Choices":
|
||||||
validate_duplicate_options(question)
|
validate_duplicate_options(question)
|
||||||
|
|||||||
Reference in New Issue
Block a user