feat: batch feedback
This commit is contained in:
47
frontend/src/components/BatchFeedback.vue
Normal file
47
frontend/src/components/BatchFeedback.vue
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="feedbackList.data"></div>
|
||||||
|
<div v-else class="space-y-8">
|
||||||
|
<div class="grid grid-cols-4 gap-5">
|
||||||
|
<Rating v-model="feedback.content" :label="__('Content')" />
|
||||||
|
<Rating v-model="feedback.delivery" :label="__('Delivery')" />
|
||||||
|
<Rating v-model="feedback.instructors" :label="__('Instructors')" />
|
||||||
|
<Rating v-model="feedback.value" :label="__('Value')" />
|
||||||
|
</div>
|
||||||
|
<FormControl
|
||||||
|
v-model="feedback.feedback"
|
||||||
|
type="textarea"
|
||||||
|
:label="__('Feedback')"
|
||||||
|
rows="7"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { inject, reactive } from 'vue'
|
||||||
|
import { createListResource, FormControl, Rating } from 'frappe-ui'
|
||||||
|
|
||||||
|
const user = inject('$user')
|
||||||
|
const feedback = reactive({
|
||||||
|
content: 0,
|
||||||
|
delivery: 0,
|
||||||
|
instructors: 0,
|
||||||
|
value: 0,
|
||||||
|
feedback: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
batch: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const feedbackList = createListResource({
|
||||||
|
doctype: 'LMS Batch Feedback',
|
||||||
|
filters: {
|
||||||
|
batch: props.batch,
|
||||||
|
member: user.data?.name,
|
||||||
|
},
|
||||||
|
cache: ['feedbackList', props.batch, user.data?.name],
|
||||||
|
auto: true,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -391,7 +391,7 @@ const getChartOptions = (categories) => {
|
|||||||
},
|
},
|
||||||
rotate: 0,
|
rotate: 0,
|
||||||
formatter: function (value) {
|
formatter: function (value) {
|
||||||
return value.length > 20 ? `${value.substring(0, 20)}...` : value // Trim long labels
|
return value.length > 20 ? `${value.substring(0, 20)}...` : value
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -77,10 +77,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <span class="mt-4">
|
|
||||||
{{ student }}
|
|
||||||
</span> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|||||||
@@ -84,6 +84,9 @@
|
|||||||
:scrollToBottom="true"
|
:scrollToBottom="true"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else-if="tab.label == 'Feedback'">
|
||||||
|
<BatchFeedback :batch="batch.data.name" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
@@ -190,12 +193,11 @@ import {
|
|||||||
BookOpen,
|
BookOpen,
|
||||||
Laptop,
|
Laptop,
|
||||||
BookOpenCheck,
|
BookOpenCheck,
|
||||||
Contact2,
|
|
||||||
Mail,
|
Mail,
|
||||||
SendIcon,
|
SendIcon,
|
||||||
MessageCircle,
|
MessageCircle,
|
||||||
Globe,
|
Globe,
|
||||||
ShieldCheck,
|
ClipboardPen,
|
||||||
} from 'lucide-vue-next'
|
} from 'lucide-vue-next'
|
||||||
import { formatTime, updateDocumentTitle } from '@/utils'
|
import { formatTime, updateDocumentTitle } from '@/utils'
|
||||||
import BatchDashboard from '@/components/BatchDashboard.vue'
|
import BatchDashboard from '@/components/BatchDashboard.vue'
|
||||||
@@ -208,6 +210,7 @@ import AnnouncementModal from '@/components/Modals/AnnouncementModal.vue'
|
|||||||
import Discussions from '@/components/Discussions.vue'
|
import Discussions from '@/components/Discussions.vue'
|
||||||
import DateRange from '@/components/Common/DateRange.vue'
|
import DateRange from '@/components/Common/DateRange.vue'
|
||||||
import BulkCertificates from '@/components/Modals/BulkCertificates.vue'
|
import BulkCertificates from '@/components/Modals/BulkCertificates.vue'
|
||||||
|
import BatchFeedback from '@/components/BatchFeedback.vue'
|
||||||
|
|
||||||
const user = inject('$user')
|
const user = inject('$user')
|
||||||
const showAnnouncementModal = ref(false)
|
const showAnnouncementModal = ref(false)
|
||||||
@@ -291,6 +294,13 @@ const tabs = computed(() => {
|
|||||||
label: 'Discussions',
|
label: 'Discussions',
|
||||||
icon: MessageCircle,
|
icon: MessageCircle,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (isStudent.value) {
|
||||||
|
batchTabs.push({
|
||||||
|
label: 'Feedback',
|
||||||
|
icon: ClipboardPen,
|
||||||
|
})
|
||||||
|
}
|
||||||
return batchTabs
|
return batchTabs
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -594,7 +594,7 @@ def get_categories(doctype, filters):
|
|||||||
def get_members(start=0, search=""):
|
def get_members(start=0, search=""):
|
||||||
"""Get members for the given search term and start index.
|
"""Get members for the given search term and start index.
|
||||||
Args: start (int): Start index for the query.
|
Args: start (int): Start index for the query.
|
||||||
search (str): Search term to filter the results.
|
search (str): Search term to filter the results.
|
||||||
Returns: List of members.
|
Returns: List of members.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
0
lms/lms/doctype/lms_batch_feedback/__init__.py
Normal file
0
lms/lms/doctype/lms_batch_feedback/__init__.py
Normal file
8
lms/lms/doctype/lms_batch_feedback/lms_batch_feedback.js
Normal file
8
lms/lms/doctype/lms_batch_feedback/lms_batch_feedback.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2025, Frappe and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
// frappe.ui.form.on("LMS Batch Feedback", {
|
||||||
|
// refresh(frm) {
|
||||||
|
|
||||||
|
// },
|
||||||
|
// });
|
||||||
90
lms/lms/doctype/lms_batch_feedback/lms_batch_feedback.json
Normal file
90
lms/lms/doctype/lms_batch_feedback/lms_batch_feedback.json
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"actions": [],
|
||||||
|
"allow_rename": 1,
|
||||||
|
"creation": "2025-01-07 18:53:22.279844",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"member",
|
||||||
|
"batch",
|
||||||
|
"feedback",
|
||||||
|
"column_break_swst",
|
||||||
|
"content",
|
||||||
|
"delivery",
|
||||||
|
"instructors",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "member",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Member",
|
||||||
|
"options": "User",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "batch",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Batch",
|
||||||
|
"options": "LMS Batch",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "feedback",
|
||||||
|
"fieldtype": "Small Text",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Feedback",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_swst",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "content",
|
||||||
|
"fieldtype": "Rating",
|
||||||
|
"label": "Content"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "delivery",
|
||||||
|
"fieldtype": "Rating",
|
||||||
|
"label": "Delivery"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "instructors",
|
||||||
|
"fieldtype": "Rating",
|
||||||
|
"label": "Instructors"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "value",
|
||||||
|
"fieldtype": "Rating",
|
||||||
|
"label": "Value"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"index_web_pages_for_search": 1,
|
||||||
|
"links": [],
|
||||||
|
"modified": "2025-01-07 18:56:38.800575",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "LMS",
|
||||||
|
"name": "LMS Batch Feedback",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sort_field": "creation",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"states": []
|
||||||
|
}
|
||||||
9
lms/lms/doctype/lms_batch_feedback/lms_batch_feedback.py
Normal file
9
lms/lms/doctype/lms_batch_feedback/lms_batch_feedback.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2025, Frappe and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
|
||||||
|
class LMSBatchFeedback(Document):
|
||||||
|
pass
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Copyright (c) 2025, Frappe and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
from frappe.tests import IntegrationTestCase, UnitTestCase
|
||||||
|
|
||||||
|
|
||||||
|
# On IntegrationTestCase, the doctype test records and all
|
||||||
|
# link-field test record dependencies are recursively loaded
|
||||||
|
# Use these module variables to add/remove to/from that list
|
||||||
|
EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
||||||
|
IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
|
||||||
|
|
||||||
|
|
||||||
|
class UnitTestLMSBatchFeedback(UnitTestCase):
|
||||||
|
"""
|
||||||
|
Unit tests for LMSBatchFeedback.
|
||||||
|
Use this class for testing individual functions and methods.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class IntegrationTestLMSBatchFeedback(IntegrationTestCase):
|
||||||
|
"""
|
||||||
|
Integration tests for LMSBatchFeedback.
|
||||||
|
Use this class for testing interactions between multiple components.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pass
|
||||||
Reference in New Issue
Block a user