refactor: moved batch feedback to sidebar
This commit is contained in:
1
frontend/components.d.ts
vendored
1
frontend/components.d.ts
vendored
@@ -52,6 +52,7 @@ declare module 'vue' {
|
|||||||
Evaluators: typeof import('./src/components/Evaluators.vue')['default']
|
Evaluators: typeof import('./src/components/Evaluators.vue')['default']
|
||||||
Event: typeof import('./src/components/Modals/Event.vue')['default']
|
Event: typeof import('./src/components/Modals/Event.vue')['default']
|
||||||
ExplanationVideos: typeof import('./src/components/Modals/ExplanationVideos.vue')['default']
|
ExplanationVideos: typeof import('./src/components/Modals/ExplanationVideos.vue')['default']
|
||||||
|
FeedbackModal: typeof import('./src/components/Modals/FeedbackModal.vue')['default']
|
||||||
FrappeCloudIcon: typeof import('./src/components/Icons/FrappeCloudIcon.vue')['default']
|
FrappeCloudIcon: typeof import('./src/components/Icons/FrappeCloudIcon.vue')['default']
|
||||||
IconPicker: typeof import('./src/components/Controls/IconPicker.vue')['default']
|
IconPicker: typeof import('./src/components/Controls/IconPicker.vue')['default']
|
||||||
IndicatorIcon: typeof import('./src/components/Icons/IndicatorIcon.vue')['default']
|
IndicatorIcon: typeof import('./src/components/Icons/IndicatorIcon.vue')['default']
|
||||||
|
|||||||
@@ -1,44 +1,49 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="user.data?.is_student">
|
<div v-if="user.data?.is_student">
|
||||||
<div
|
<div>
|
||||||
v-if="feedbackList.data?.length"
|
<div class="leading-5 mb-4">
|
||||||
class="bg-surface-blue-2 text-blue-700 p-2 rounded-md mb-5"
|
<div v-if="readOnly">
|
||||||
>
|
{{ __('Thank you for providing your feedback.') }}
|
||||||
{{ __('Thank you for providing your feedback!') }}
|
<span
|
||||||
</div>
|
@click="showFeedbackForm = !showFeedbackForm"
|
||||||
<div v-else class="flex justify-between items-center mb-5">
|
class="underline cursor-pointer"
|
||||||
<div class="text-lg font-semibold">
|
>{{ __('Click here') }}</span
|
||||||
{{ __('Help Us Improve') }}
|
>
|
||||||
|
{{ __('to view your feedback.') }}
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
{{ __('Help us improve by providing your feedback.') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Button @click="submitFeedback()">
|
<div class="space-y-4" :class="showFeedbackForm ? 'block' : 'hidden'">
|
||||||
{{ __('Submit') }}
|
<div class="space-y-4">
|
||||||
</Button>
|
<Rating
|
||||||
</div>
|
v-for="key in ratingKeys"
|
||||||
<div class="space-y-8">
|
v-model="feedback[key]"
|
||||||
<div class="flex items-center justify-between">
|
:label="__(convertToTitleCase(key))"
|
||||||
<Rating
|
:readonly="readOnly"
|
||||||
v-for="key in ratingKeys"
|
/>
|
||||||
v-model="feedback[key]"
|
</div>
|
||||||
:label="__(convertToTitleCase(key))"
|
<FormControl
|
||||||
|
v-model="feedback.feedback"
|
||||||
|
type="textarea"
|
||||||
|
:label="__('Feedback')"
|
||||||
|
:rows="9"
|
||||||
:readonly="readOnly"
|
:readonly="readOnly"
|
||||||
/>
|
/>
|
||||||
|
<Button v-if="!readOnly" @click="submitFeedback">
|
||||||
|
{{ __('Submit Feedback') }}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<FormControl
|
|
||||||
v-model="feedback.feedback"
|
|
||||||
type="textarea"
|
|
||||||
:label="__('Feedback')"
|
|
||||||
:rows="7"
|
|
||||||
:readonly="readOnly"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else-if="feedbackList.data?.length">
|
<div v-else-if="feedbackList.data?.length">
|
||||||
<div class="text-lg font-semibold mb-5">
|
<div class="leading-5 text-sm mb-2 mt-5">
|
||||||
{{ __('Average of Feedback Received') }}
|
{{ __('Average Feedback Received') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center justify-between mb-10">
|
<div class="space-y-4">
|
||||||
<Rating
|
<Rating
|
||||||
v-for="key in ratingKeys"
|
v-for="key in ratingKeys"
|
||||||
v-model="average[key]"
|
v-model="average[key]"
|
||||||
@@ -47,81 +52,32 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-lg font-semibold mb-5">
|
<Button variant="outline" class="mt-5" @click="showAllFeedback = true">
|
||||||
{{ __('All Feedback') }}
|
{{ __('View all feedback') }}
|
||||||
</div>
|
</Button>
|
||||||
<ListView
|
|
||||||
:columns="feedbackColumns"
|
|
||||||
:rows="feedbackList.data"
|
|
||||||
row-key="name"
|
|
||||||
:options="{
|
|
||||||
showTooltip: false,
|
|
||||||
rowHeight: 'h-16',
|
|
||||||
selectable: false,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<ListHeader
|
|
||||||
class="mb-2 grid items-center space-x-4 rounded bg-surface-gray-2 p-2"
|
|
||||||
></ListHeader>
|
|
||||||
<ListRows>
|
|
||||||
<ListRow
|
|
||||||
:row="row"
|
|
||||||
v-for="row in feedbackList.data"
|
|
||||||
class="group cursor-pointer feedback-list"
|
|
||||||
>
|
|
||||||
<template #default="{ column, item }">
|
|
||||||
<ListRowItem
|
|
||||||
:item="row[column.key]"
|
|
||||||
:align="column.align"
|
|
||||||
class="text-sm"
|
|
||||||
>
|
|
||||||
<template #prefix>
|
|
||||||
<div v-if="column.key == 'member_name'">
|
|
||||||
<Avatar
|
|
||||||
class="flex"
|
|
||||||
:image="row['member_image']"
|
|
||||||
:label="item"
|
|
||||||
size="sm"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div v-if="ratingKeys.includes(column.key)">
|
|
||||||
<Rating v-model="row[column.key]" :readonly="true" />
|
|
||||||
</div>
|
|
||||||
<div v-else class="leading-5">
|
|
||||||
{{ row[column.key] }}
|
|
||||||
</div>
|
|
||||||
</ListRowItem>
|
|
||||||
</template>
|
|
||||||
</ListRow>
|
|
||||||
</ListRows>
|
|
||||||
</ListView>
|
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="text-sm italic text-center text-ink-gray-7 mt-5">
|
<div v-else class="text-ink-gray-7 mt-5 leading-5">
|
||||||
{{ __('No feedback received yet.') }}
|
{{ __('No feedback received yet.') }}
|
||||||
</div>
|
</div>
|
||||||
|
<FeedbackModal
|
||||||
|
v-if="feedbackList.data?.length"
|
||||||
|
v-model="showAllFeedback"
|
||||||
|
:feedbackList="feedbackList.data"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, inject, onMounted, reactive, ref, watch } from 'vue'
|
import { inject, onMounted, reactive, ref, watch } from 'vue'
|
||||||
import { convertToTitleCase } from '@/utils'
|
import { convertToTitleCase } from '@/utils'
|
||||||
import {
|
import { Button, createListResource, FormControl, Rating } from 'frappe-ui'
|
||||||
Avatar,
|
import FeedbackModal from '@/components/Modals/FeedbackModal.vue'
|
||||||
Button,
|
|
||||||
createListResource,
|
|
||||||
FormControl,
|
|
||||||
ListView,
|
|
||||||
ListHeader,
|
|
||||||
ListRows,
|
|
||||||
ListRow,
|
|
||||||
ListRowItem,
|
|
||||||
Rating,
|
|
||||||
} from 'frappe-ui'
|
|
||||||
|
|
||||||
const user = inject('$user')
|
const user = inject('$user')
|
||||||
const ratingKeys = ['content', 'instructors', 'value']
|
const ratingKeys = ['content', 'instructors', 'value']
|
||||||
const readOnly = ref(false)
|
const readOnly = ref(false)
|
||||||
const average = reactive({})
|
const average = reactive({})
|
||||||
const feedback = reactive({})
|
const feedback = reactive({})
|
||||||
|
const showFeedbackForm = ref(true)
|
||||||
|
const showAllFeedback = ref(false)
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
batch: {
|
batch: {
|
||||||
@@ -167,6 +123,7 @@ watch(
|
|||||||
if (feedbackList.data.length) {
|
if (feedbackList.data.length) {
|
||||||
let data = feedbackList.data
|
let data = feedbackList.data
|
||||||
readOnly.value = true
|
readOnly.value = true
|
||||||
|
showFeedbackForm.value = false
|
||||||
|
|
||||||
ratingKeys.forEach((key) => {
|
ratingKeys.forEach((key) => {
|
||||||
average[key] = 0
|
average[key] = 0
|
||||||
@@ -201,40 +158,11 @@ const submitFeedback = () => {
|
|||||||
{
|
{
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
feedbackList.reload()
|
feedbackList.reload()
|
||||||
|
showFeedbackForm.value = false
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const feedbackColumns = computed(() => {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
label: 'Member',
|
|
||||||
key: 'member_name',
|
|
||||||
width: '10rem',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Feedback',
|
|
||||||
key: 'feedback',
|
|
||||||
width: '15rem',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Content',
|
|
||||||
key: 'content',
|
|
||||||
width: '9rem',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Instructors',
|
|
||||||
key: 'instructors',
|
|
||||||
width: '9rem',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Value',
|
|
||||||
key: 'value',
|
|
||||||
width: '9rem',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.feedback-list > button > div {
|
.feedback-list > button > div {
|
||||||
|
|||||||
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>
|
||||||
@@ -88,56 +88,61 @@
|
|||||||
:scrollToBottom="false"
|
:scrollToBottom="false"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab.label == 'Feedback'">
|
|
||||||
<BatchFeedback :batch="batch.data.name" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-5">
|
<div class="p-5">
|
||||||
<div class="text-ink-gray-7 font-semibold mb-4">
|
<div class="mb-10">
|
||||||
{{ __('About this batch') }}:
|
<div class="text-ink-gray-7 font-semibold mb-2">
|
||||||
</div>
|
{{ __('About this batch') }}
|
||||||
<div
|
</div>
|
||||||
v-html="batch.data.description"
|
<div
|
||||||
class="leading-5 mb-4 text-ink-gray-7"
|
v-html="batch.data.description"
|
||||||
></div>
|
class="leading-5 mb-4 text-ink-gray-7"
|
||||||
|
></div>
|
||||||
<div class="flex items-center avatar-group overlap mb-5">
|
|
||||||
<div
|
<div class="flex items-center avatar-group overlap mb-5">
|
||||||
class="h-6 mr-1"
|
<div
|
||||||
:class="{
|
class="h-6 mr-1"
|
||||||
'avatar-group overlap': batch.data.instructors.length > 1,
|
:class="{
|
||||||
}"
|
'avatar-group overlap': batch.data.instructors.length > 1,
|
||||||
>
|
}"
|
||||||
<UserAvatar
|
>
|
||||||
v-for="instructor in batch.data.instructors"
|
<UserAvatar
|
||||||
:user="instructor"
|
v-for="instructor in batch.data.instructors"
|
||||||
/>
|
:user="instructor"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<CourseInstructors :instructors="batch.data.instructors" />
|
||||||
|
</div>
|
||||||
|
<DateRange
|
||||||
|
:startDate="batch.data.start_date"
|
||||||
|
:endDate="batch.data.end_date"
|
||||||
|
class="mb-3"
|
||||||
|
/>
|
||||||
|
<div class="flex items-center mb-4 text-ink-gray-7">
|
||||||
|
<Clock class="h-4 w-4 stroke-1.5 mr-2" />
|
||||||
|
<span>
|
||||||
|
{{ formatTime(batch.data.start_time) }} -
|
||||||
|
{{ formatTime(batch.data.end_time) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="batch.data.timezone"
|
||||||
|
class="flex items-center mb-4 text-ink-gray-7"
|
||||||
|
>
|
||||||
|
<Globe class="h-4 w-4 stroke-1.5 mr-2" />
|
||||||
|
<span>
|
||||||
|
{{ batch.data.timezone }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<CourseInstructors :instructors="batch.data.instructors" />
|
|
||||||
</div>
|
</div>
|
||||||
<DateRange
|
<div v-if="batch.data?.start_date <= dayjs().format('YYYY-MM-DD')">
|
||||||
:startDate="batch.data.start_date"
|
<div class="text-ink-gray-7 font-semibold mb-2">
|
||||||
:endDate="batch.data.end_date"
|
{{ __('Feedback') }}
|
||||||
class="mb-3"
|
</div>
|
||||||
/>
|
<BatchFeedback :batch="batch.data?.name" />
|
||||||
<div class="flex items-center mb-4 text-ink-gray-7">
|
|
||||||
<Clock class="h-4 w-4 stroke-1.5 mr-2" />
|
|
||||||
<span>
|
|
||||||
{{ formatTime(batch.data.start_time) }} -
|
|
||||||
{{ formatTime(batch.data.end_time) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="batch.data.timezone"
|
|
||||||
class="flex items-center mb-4 text-ink-gray-7"
|
|
||||||
>
|
|
||||||
<Globe class="h-4 w-4 stroke-1.5 mr-2" />
|
|
||||||
<span>
|
|
||||||
{{ batch.data.timezone }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<AnnouncementModal
|
<AnnouncementModal
|
||||||
@@ -234,6 +239,7 @@ import Discussions from '@/components/Discussions.vue'
|
|||||||
import DateRange from '@/components/Common/DateRange.vue'
|
import DateRange from '@/components/Common/DateRange.vue'
|
||||||
import BulkCertificates from '@/components/Modals/BulkCertificates.vue'
|
import BulkCertificates from '@/components/Modals/BulkCertificates.vue'
|
||||||
import BatchFeedback from '@/components/BatchFeedback.vue'
|
import BatchFeedback from '@/components/BatchFeedback.vue'
|
||||||
|
import dayjs from 'dayjs/esm'
|
||||||
|
|
||||||
const user = inject('$user')
|
const user = inject('$user')
|
||||||
const showAnnouncementModal = ref(false)
|
const showAnnouncementModal = ref(false)
|
||||||
@@ -277,11 +283,6 @@ const tabs = computed(() => {
|
|||||||
label: 'Discussions',
|
label: 'Discussions',
|
||||||
icon: MessageCircle,
|
icon: MessageCircle,
|
||||||
})
|
})
|
||||||
|
|
||||||
batchTabs.push({
|
|
||||||
label: 'Feedback',
|
|
||||||
icon: ClipboardPen,
|
|
||||||
})
|
|
||||||
return batchTabs
|
return batchTabs
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -20,14 +20,12 @@
|
|||||||
</header>
|
</header>
|
||||||
<div class="p-5 pb-10">
|
<div class="p-5 pb-10">
|
||||||
<div
|
<div
|
||||||
v-if="batchCount"
|
|
||||||
class="flex flex-col lg:flex-row space-y-4 lg:space-y-0 lg:items-center justify-between mb-5"
|
class="flex flex-col lg:flex-row space-y-4 lg:space-y-0 lg:items-center justify-between mb-5"
|
||||||
>
|
>
|
||||||
<div class="text-lg text-ink-gray-9 font-semibold">
|
<div class="text-lg text-ink-gray-9 font-semibold">
|
||||||
{{ __('All Batches') }}
|
{{ __('All Batches') }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="batches.data?.length || batchCount"
|
|
||||||
class="flex flex-col space-y-2 lg:space-y-0 lg:flex-row lg:items-center lg:space-x-4"
|
class="flex flex-col space-y-2 lg:space-y-0 lg:flex-row lg:items-center lg:space-x-4"
|
||||||
>
|
>
|
||||||
<TabButtons
|
<TabButtons
|
||||||
@@ -115,12 +113,10 @@ const is_student = computed(() => user.data?.is_student)
|
|||||||
const currentTab = ref(is_student.value ? 'All' : 'Upcoming')
|
const currentTab = ref(is_student.value ? 'All' : 'Upcoming')
|
||||||
const orderBy = ref('start_date')
|
const orderBy = ref('start_date')
|
||||||
const readOnlyMode = window.read_only_mode
|
const readOnlyMode = window.read_only_mode
|
||||||
const batchCount = ref(0)
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
setFiltersFromQuery()
|
setFiltersFromQuery()
|
||||||
updateBatches()
|
updateBatches()
|
||||||
getBatchCount()
|
|
||||||
categories.value = [
|
categories.value = [
|
||||||
{
|
{
|
||||||
label: '',
|
label: '',
|
||||||
@@ -298,14 +294,6 @@ const canCreateBatch = () => {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
const getBatchCount = () => {
|
|
||||||
call('frappe.client.get_count', {
|
|
||||||
doctype: 'LMS Batch',
|
|
||||||
}).then((data) => {
|
|
||||||
batchCount.value = data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const breadcrumbs = computed(() => [
|
const breadcrumbs = computed(() => [
|
||||||
{
|
{
|
||||||
label: __('Batches'),
|
label: __('Batches'),
|
||||||
|
|||||||
@@ -20,14 +20,12 @@
|
|||||||
</header>
|
</header>
|
||||||
<div class="p-5 pb-10">
|
<div class="p-5 pb-10">
|
||||||
<div
|
<div
|
||||||
v-if="courseCount"
|
|
||||||
class="flex flex-col lg:flex-row space-y-4 lg:space-y-0 lg:items-center justify-between mb-5"
|
class="flex flex-col lg:flex-row space-y-4 lg:space-y-0 lg:items-center justify-between mb-5"
|
||||||
>
|
>
|
||||||
<div class="text-lg text-ink-gray-9 font-semibold">
|
<div class="text-lg text-ink-gray-9 font-semibold">
|
||||||
{{ __('All Courses') }}
|
{{ __('All Courses') }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="courses.data?.length || courseCount"
|
|
||||||
class="flex flex-col space-y-2 lg:space-y-0 lg:flex-row lg:items-center lg:space-x-4"
|
class="flex flex-col space-y-2 lg:space-y-0 lg:flex-row lg:items-center lg:space-x-4"
|
||||||
>
|
>
|
||||||
<TabButtons :buttons="courseTabs" v-model="currentTab" />
|
<TabButtons :buttons="courseTabs" v-model="currentTab" />
|
||||||
@@ -172,6 +170,8 @@ const identifyUserPersona = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getCourseCount = () => {
|
const getCourseCount = () => {
|
||||||
|
if (!user.data) return
|
||||||
|
|
||||||
call('frappe.client.get_count', {
|
call('frappe.client.get_count', {
|
||||||
doctype: 'LMS Course',
|
doctype: 'LMS Course',
|
||||||
}).then((data) => {
|
}).then((data) => {
|
||||||
|
|||||||
@@ -356,6 +356,7 @@
|
|||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"grid_page_length": 50,
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [
|
"links": [
|
||||||
{
|
{
|
||||||
@@ -371,8 +372,8 @@
|
|||||||
"link_fieldname": "batch_name"
|
"link_fieldname": "batch_name"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2025-02-18 15:43:18.512504",
|
"modified": "2025-05-21 13:30:28.904260",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "sayali@frappe.io",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Batch",
|
"name": "LMS Batch",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
@@ -412,12 +413,22 @@
|
|||||||
"role": "Batch Evaluator",
|
"role": "Batch Evaluator",
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "LMS Student",
|
||||||
|
"share": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"row_format": "Dynamic",
|
||||||
"show_title_field_in_link": 1,
|
"show_title_field_in_link": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": [],
|
"states": [],
|
||||||
"title_field": "title",
|
"title_field": "title",
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,10 +73,11 @@
|
|||||||
"read_only": 1
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"grid_page_length": 50,
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-01-13 19:02:58.259908",
|
"modified": "2025-05-21 15:58:51.667270",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "sayali@frappe.io",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Batch Feedback",
|
"name": "LMS Batch Feedback",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
@@ -106,7 +107,9 @@
|
|||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"row_format": "Dynamic",
|
||||||
"sort_field": "creation",
|
"sort_field": "creation",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": []
|
"states": [],
|
||||||
}
|
"title_field": "member"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user