Merge pull request #932 from pateljannat/batch-categories
feat: batch categories filter
This commit is contained in:
@@ -7,7 +7,15 @@
|
|||||||
class="h-7"
|
class="h-7"
|
||||||
:items="[{ label: __('All Batches'), route: { name: 'Batches' } }]"
|
:items="[{ label: __('All Batches'), route: { name: 'Batches' } }]"
|
||||||
/>
|
/>
|
||||||
<div class="flex">
|
<div class="flex space-x-2">
|
||||||
|
<div class="w-40">
|
||||||
|
<Select
|
||||||
|
v-if="categories.data?.length"
|
||||||
|
v-model="currentCategory"
|
||||||
|
:options="categories.data"
|
||||||
|
:placeholder="__('Filter')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="user.data?.is_moderator"
|
v-if="user.data?.is_moderator"
|
||||||
:to="{
|
:to="{
|
||||||
@@ -33,7 +41,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<Tabs
|
<Tabs
|
||||||
v-model="tabIndex"
|
v-model="tabIndex"
|
||||||
:tabs="tabs"
|
:tabs="makeTabs"
|
||||||
tablistClass="overflow-x-visible flex-wrap !gap-3 md:flex-nowrap"
|
tablistClass="overflow-x-visible flex-wrap !gap-3 md:flex-nowrap"
|
||||||
>
|
>
|
||||||
<template #tab="{ tab, selected }">
|
<template #tab="{ tab, selected }">
|
||||||
@@ -87,13 +95,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { createListResource, Breadcrumbs, Button, Tabs, Badge } from 'frappe-ui'
|
import {
|
||||||
|
createListResource,
|
||||||
|
createResource,
|
||||||
|
Breadcrumbs,
|
||||||
|
Button,
|
||||||
|
Tabs,
|
||||||
|
Badge,
|
||||||
|
Select,
|
||||||
|
} from 'frappe-ui'
|
||||||
import { Plus } from 'lucide-vue-next'
|
import { Plus } from 'lucide-vue-next'
|
||||||
import BatchCard from '@/components/BatchCard.vue'
|
import BatchCard from '@/components/BatchCard.vue'
|
||||||
import { inject, ref, computed } from 'vue'
|
import { inject, ref, computed, onMounted, watch } from 'vue'
|
||||||
import { updateDocumentTitle } from '@/utils'
|
import { updateDocumentTitle } from '@/utils'
|
||||||
|
|
||||||
const user = inject('$user')
|
const user = inject('$user')
|
||||||
|
const currentCategory = ref(null)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
let queries = new URLSearchParams(location.search)
|
||||||
|
if (queries.has('category')) {
|
||||||
|
currentCategory.value = queries.get('category')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const batches = createListResource({
|
const batches = createListResource({
|
||||||
doctype: 'LMS Batch',
|
doctype: 'LMS Batch',
|
||||||
@@ -102,35 +126,76 @@ const batches = createListResource({
|
|||||||
auto: true,
|
auto: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const tabIndex = ref(0)
|
const categories = createResource({
|
||||||
const tabs = [
|
url: 'lms.lms.api.get_categories',
|
||||||
{
|
makeParams() {
|
||||||
label: 'Upcoming',
|
return {
|
||||||
batches: computed(() => batches.data?.upcoming || []),
|
doctype: 'LMS Batch',
|
||||||
count: computed(() => batches.data?.upcoming?.length),
|
filters: {
|
||||||
|
published: 1,
|
||||||
},
|
},
|
||||||
]
|
}
|
||||||
|
},
|
||||||
|
cache: ['batchCategories'],
|
||||||
|
auto: true,
|
||||||
|
transform(data) {
|
||||||
|
data.unshift({
|
||||||
|
label: '',
|
||||||
|
value: null,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
if (user.data?.is_moderator) {
|
const tabIndex = ref(0)
|
||||||
|
let tabs
|
||||||
|
|
||||||
|
const makeTabs = computed(() => {
|
||||||
|
tabs = []
|
||||||
|
addToTabs('Upcoming')
|
||||||
|
|
||||||
|
if (user.data?.is_moderator) {
|
||||||
|
addToTabs('Archived')
|
||||||
|
addToTabs('Private')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.data) {
|
||||||
|
addToTabs('Enrolled')
|
||||||
|
}
|
||||||
|
|
||||||
|
return tabs
|
||||||
|
})
|
||||||
|
|
||||||
|
const getBatches = (type) => {
|
||||||
|
if (currentCategory.value && currentCategory.value != '') {
|
||||||
|
return batches.data[type].filter(
|
||||||
|
(batch) => batch.category == currentCategory.value
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return batches.data[type]
|
||||||
|
}
|
||||||
|
|
||||||
|
const addToTabs = (label) => {
|
||||||
|
let batches = getBatches(label.toLowerCase().split(' ').join('_'))
|
||||||
tabs.push({
|
tabs.push({
|
||||||
label: 'Archived',
|
label,
|
||||||
batches: computed(() => batches.data?.archived),
|
batches: computed(() => batches),
|
||||||
count: computed(() => batches.data?.archived?.length),
|
count: computed(() => batches.length),
|
||||||
})
|
|
||||||
tabs.push({
|
|
||||||
label: 'Private',
|
|
||||||
batches: computed(() => batches.data?.private),
|
|
||||||
count: computed(() => batches.data?.private?.length),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (user.data) {
|
|
||||||
tabs.push({
|
|
||||||
label: 'Enrolled',
|
|
||||||
batches: computed(() => batches.data?.enrolled),
|
|
||||||
count: computed(() => batches.data?.enrolled?.length),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => currentCategory.value,
|
||||||
|
() => {
|
||||||
|
let queries = new URLSearchParams(location.search)
|
||||||
|
if (currentCategory.value) {
|
||||||
|
queries.set('category', currentCategory.value)
|
||||||
|
} else {
|
||||||
|
queries.delete('category')
|
||||||
|
}
|
||||||
|
history.pushState(null, '', `${location.pathname}?${queries.toString()}`)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const pageMeta = computed(() => {
|
const pageMeta = computed(() => {
|
||||||
return {
|
return {
|
||||||
title: 'Batches',
|
title: 'Batches',
|
||||||
|
|||||||
@@ -134,29 +134,30 @@ let tabs
|
|||||||
|
|
||||||
const makeTabs = computed(() => {
|
const makeTabs = computed(() => {
|
||||||
tabs = []
|
tabs = []
|
||||||
addToTabs('Live', getCourses('live'))
|
addToTabs('Live')
|
||||||
addToTabs('New', getCourses('new'))
|
addToTabs('New')
|
||||||
addToTabs('Upcoming', getCourses('upcoming'))
|
addToTabs('Upcoming')
|
||||||
|
|
||||||
if (user.data) {
|
if (user.data) {
|
||||||
addToTabs('Enrolled', getCourses('enrolled'))
|
addToTabs('Enrolled')
|
||||||
|
|
||||||
if (
|
if (
|
||||||
user.data.is_moderator ||
|
user.data.is_moderator ||
|
||||||
user.data.is_instructor ||
|
user.data.is_instructor ||
|
||||||
courses.data?.created?.length
|
courses.data?.created?.length
|
||||||
) {
|
) {
|
||||||
addToTabs('Created', getCourses('created'))
|
addToTabs('Created')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.data.is_moderator) {
|
if (user.data.is_moderator) {
|
||||||
addToTabs('Under Review', getCourses('under_review'))
|
addToTabs('Under Review')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tabs
|
return tabs
|
||||||
})
|
})
|
||||||
|
|
||||||
const addToTabs = (label, courses) => {
|
const addToTabs = (label) => {
|
||||||
|
let courses = getCourses(label.toLowerCase().split(' ').join('_'))
|
||||||
tabs.push({
|
tabs.push({
|
||||||
label,
|
label,
|
||||||
courses: computed(() => courses),
|
courses: computed(() => courses),
|
||||||
@@ -166,8 +167,12 @@ const addToTabs = (label, courses) => {
|
|||||||
|
|
||||||
const getCourses = (type) => {
|
const getCourses = (type) => {
|
||||||
if (searchQuery.value) {
|
if (searchQuery.value) {
|
||||||
return courses.data[type].filter((course) =>
|
let query = searchQuery.value.toLowerCase()
|
||||||
course.title.toLowerCase().includes(searchQuery.value.toLowerCase())
|
return courses.data[type].filter(
|
||||||
|
(course) =>
|
||||||
|
course.title.toLowerCase().includes(query) ||
|
||||||
|
course.short_introduction.toLowerCase().includes(query) ||
|
||||||
|
course.tags.filter((tag) => tag.toLowerCase().includes(query)).length
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return courses.data[type]
|
return courses.data[type]
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import router from '@/router'
|
|||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
|
|
||||||
export const sessionStore = defineStore('lms-session', () => {
|
export const sessionStore = defineStore('lms-session', () => {
|
||||||
let { userResource } = usersStore()
|
let { userResource, allUsers } = usersStore()
|
||||||
|
|
||||||
function sessionUser() {
|
function sessionUser() {
|
||||||
let cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
|
let cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
|
||||||
@@ -17,6 +17,9 @@ export const sessionStore = defineStore('lms-session', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let user = ref(sessionUser())
|
let user = ref(sessionUser())
|
||||||
|
if (user) {
|
||||||
|
allUsers.reload()
|
||||||
|
}
|
||||||
const isLoggedIn = computed(() => !!user.value)
|
const isLoggedIn = computed(() => !!user.value)
|
||||||
|
|
||||||
const login = createResource({
|
const login = createResource({
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ export const usersStore = defineStore('lms-users', () => {
|
|||||||
const allUsers = createResource({
|
const allUsers = createResource({
|
||||||
url: 'lms.lms.api.get_all_users',
|
url: 'lms.lms.api.get_all_users',
|
||||||
cache: ['allUsers'],
|
cache: ['allUsers'],
|
||||||
auto: true,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -542,3 +542,21 @@ def update_index(lessons, chapter):
|
|||||||
frappe.db.set_value(
|
frappe.db.set_value(
|
||||||
"Lesson Reference", {"lesson": row, "parent": chapter}, "idx", lessons.index(row) + 1
|
"Lesson Reference", {"lesson": row, "parent": chapter}, "idx", lessons.index(row) + 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist(allow_guest=True)
|
||||||
|
def get_categories(doctype, filters):
|
||||||
|
categoryOptions = []
|
||||||
|
|
||||||
|
categories = frappe.get_all(
|
||||||
|
doctype,
|
||||||
|
filters,
|
||||||
|
pluck="category",
|
||||||
|
)
|
||||||
|
categories = list(set(categories))
|
||||||
|
|
||||||
|
for category in categories:
|
||||||
|
if category:
|
||||||
|
categoryOptions.append({"label": category, "value": category})
|
||||||
|
|
||||||
|
return categoryOptions
|
||||||
|
|||||||
@@ -1456,6 +1456,7 @@ def get_batch_details(batch):
|
|||||||
"evaluation_end_date",
|
"evaluation_end_date",
|
||||||
"allow_self_enrollment",
|
"allow_self_enrollment",
|
||||||
"timezone",
|
"timezone",
|
||||||
|
"category",
|
||||||
],
|
],
|
||||||
as_dict=True,
|
as_dict=True,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user