feat: broke down sidebar into categories
This commit is contained in:
@@ -9,11 +9,21 @@
|
||||
>
|
||||
<UserDropdown :isCollapsed="sidebarStore.isSidebarCollapsed" />
|
||||
<div class="flex flex-col" v-if="sidebarSettings.data">
|
||||
<div v-for="link in sidebarLinks" class="mx-2 my-0.5">
|
||||
<SidebarLink
|
||||
:link="link"
|
||||
:isCollapsed="sidebarStore.isSidebarCollapsed"
|
||||
/>
|
||||
<div v-for="link in sidebarLinks" class="mx-2 my-2.5">
|
||||
<div
|
||||
v-if="!link.hideLabel"
|
||||
class="mb-2 mt-3 flex cursor-pointer gap-1.5 px-1 text-base font-medium text-ink-gray-5 transition-all duration-300 ease-in-out"
|
||||
>
|
||||
<span>{{ __(link.label) }}</span>
|
||||
</div>
|
||||
<nav class="space-y-1">
|
||||
<div v-for="item in link.items">
|
||||
<SidebarLink
|
||||
:link="item"
|
||||
:isCollapsed="sidebarStore.isSidebarCollapsed"
|
||||
/>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -235,18 +245,13 @@ const { userResource } = usersStore()
|
||||
let sidebarStore = useSidebar()
|
||||
const socket = inject('$socket')
|
||||
const unreadCount = ref(0)
|
||||
const sidebarLinks = ref(getSidebarLinks())
|
||||
const sidebarLinks = ref(null)
|
||||
const showPageModal = ref(false)
|
||||
const isModerator = ref(false)
|
||||
const isInstructor = ref(false)
|
||||
const pageToEdit = ref(null)
|
||||
const {
|
||||
settings,
|
||||
sidebarSettings,
|
||||
activeTab,
|
||||
isSettingsOpen,
|
||||
isCommandPaletteOpen,
|
||||
} = useSettings()
|
||||
const { settings, sidebarSettings, activeTab, isSettingsOpen, programs } =
|
||||
useSettings()
|
||||
const settingsStore = useSettings()
|
||||
const showOnboarding = ref(false)
|
||||
const showIntermediateModal = ref(false)
|
||||
@@ -262,8 +267,6 @@ const iconProps = {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
addNotifications()
|
||||
setSidebarLinks()
|
||||
setUpOnboarding()
|
||||
addKeyboardShortcut()
|
||||
socket.on('publish_lms_notifications', (data) => {
|
||||
@@ -278,9 +281,14 @@ const setSidebarLinks = () => {
|
||||
onSuccess(data) {
|
||||
Object.keys(data).forEach((key) => {
|
||||
if (!parseInt(data[key])) {
|
||||
sidebarLinks.value = sidebarLinks.value.filter(
|
||||
sidebarLinks.value.forEach((link) => {
|
||||
link.items = link.items.filter(
|
||||
(item) => item.label.toLowerCase().split(' ').join('_') !== key
|
||||
)
|
||||
})
|
||||
/* sidebarLinks.value = sidebarLinks.value?.items.filter(
|
||||
(link) => link.label.toLowerCase().split(' ').join('_') !== key
|
||||
)
|
||||
) */
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -319,85 +327,16 @@ const unreadNotifications = createResource({
|
||||
},
|
||||
onSuccess(data) {
|
||||
unreadCount.value = data
|
||||
sidebarLinks.value = sidebarLinks.value.map((link) => {
|
||||
/* sidebarLinks.value = sidebarLinks.value.map((link) => {
|
||||
if (link.label === 'Notifications') {
|
||||
link.count = data
|
||||
}
|
||||
return link
|
||||
})
|
||||
}) */
|
||||
},
|
||||
auto: user ? true : false,
|
||||
})
|
||||
|
||||
const addNotifications = () => {
|
||||
if (user) {
|
||||
sidebarLinks.value.push({
|
||||
label: 'Notifications',
|
||||
icon: 'Bell',
|
||||
to: 'Notifications',
|
||||
activeFor: ['Notifications'],
|
||||
count: unreadCount.value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const addQuizzes = () => {
|
||||
if (!isInstructor.value && !isModerator.value) return
|
||||
|
||||
const quizzesLinkExists = sidebarLinks.value.some(
|
||||
(link) => link.label === 'Quizzes'
|
||||
)
|
||||
if (quizzesLinkExists) return
|
||||
|
||||
sidebarLinks.value.splice(4, 0, {
|
||||
label: 'Quizzes',
|
||||
icon: 'CircleHelp',
|
||||
to: 'Quizzes',
|
||||
activeFor: ['Quizzes', 'QuizForm', 'QuizSubmissionList', 'QuizSubmission'],
|
||||
})
|
||||
}
|
||||
|
||||
const addAssignments = () => {
|
||||
if (!isInstructor.value && !isModerator.value) return
|
||||
|
||||
const assignmentsLinkExists = sidebarLinks.value.some(
|
||||
(link) => link.label === 'Assignments'
|
||||
)
|
||||
if (assignmentsLinkExists) return
|
||||
|
||||
sidebarLinks.value.splice(5, 0, {
|
||||
label: 'Assignments',
|
||||
icon: 'Pencil',
|
||||
to: 'Assignments',
|
||||
activeFor: [
|
||||
'Assignments',
|
||||
'AssignmentForm',
|
||||
'AssignmentSubmissionList',
|
||||
'AssignmentSubmission',
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
const addProgrammingExercises = () => {
|
||||
if (!isInstructor.value && !isModerator.value) return
|
||||
const programmingExercisesLinkExists = sidebarLinks.value.some(
|
||||
(link) => link.label === 'Programming Exercises'
|
||||
)
|
||||
if (programmingExercisesLinkExists) return
|
||||
|
||||
sidebarLinks.value.splice(3, 0, {
|
||||
label: 'Programming Exercises',
|
||||
icon: 'Code',
|
||||
to: 'ProgrammingExercises',
|
||||
activeFor: [
|
||||
'ProgrammingExercises',
|
||||
'ProgrammingExerciseForm',
|
||||
'ProgrammingExerciseSubmissions',
|
||||
'ProgrammingExerciseSubmission',
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
const addPrograms = async () => {
|
||||
const programsLinkExists = sidebarLinks.value.some(
|
||||
(link) => link.label === 'Programs'
|
||||
@@ -417,45 +356,6 @@ const addPrograms = async () => {
|
||||
})
|
||||
}
|
||||
|
||||
const addContactUsDetails = () => {
|
||||
if (!settings?.data?.contact_us_email && !settings?.data?.contact_us_url)
|
||||
return
|
||||
|
||||
const contactUsLinkExists = sidebarLinks.value.some(
|
||||
(link) => link.label === 'Contact Us'
|
||||
)
|
||||
if (contactUsLinkExists) return
|
||||
|
||||
sidebarLinks.value.push({
|
||||
label: 'Contact Us',
|
||||
icon: settings.data?.contact_us_url ? 'Headset' : 'Mail',
|
||||
to: settings.data?.contact_us_url
|
||||
? settings.data?.contact_us_url
|
||||
: settings.data?.contact_us_email,
|
||||
})
|
||||
}
|
||||
|
||||
const checkIfCanAddProgram = async () => {
|
||||
if (isModerator.value || isInstructor.value) {
|
||||
return true
|
||||
}
|
||||
const programs = await call('lms.lms.utils.get_programs')
|
||||
return programs.enrolled.length > 0 || programs.published.length > 0
|
||||
}
|
||||
|
||||
const addHome = () => {
|
||||
const homeLinkExists = sidebarLinks.value.some(
|
||||
(link) => link.label === 'Home'
|
||||
)
|
||||
if (homeLinkExists) return
|
||||
sidebarLinks.value.unshift({
|
||||
label: 'Home',
|
||||
icon: 'Home',
|
||||
to: 'Home',
|
||||
activeFor: ['Home'],
|
||||
})
|
||||
}
|
||||
|
||||
const openPageModal = (link) => {
|
||||
showPageModal.value = true
|
||||
pageToEdit.value = link
|
||||
@@ -700,16 +600,15 @@ const setUpOnboarding = () => {
|
||||
}
|
||||
}
|
||||
|
||||
watch(userResource, () => {
|
||||
addContactUsDetails()
|
||||
watch(userResource, async () => {
|
||||
await userResource.promise
|
||||
sidebarLinks.value = getSidebarLinks()
|
||||
setSidebarLinks()
|
||||
if (userResource.data) {
|
||||
isModerator.value = userResource.data.is_moderator
|
||||
isInstructor.value = userResource.data.is_instructor
|
||||
addHome()
|
||||
addPrograms()
|
||||
addProgrammingExercises()
|
||||
addQuizzes()
|
||||
addAssignments()
|
||||
await programs.promise
|
||||
sidebarLinks.value = getSidebarLinks()
|
||||
setUpOnboarding()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { createResource } from 'frappe-ui'
|
||||
import { sessionStore } from './session'
|
||||
|
||||
export const useSettings = defineStore('settings', () => {
|
||||
const isSettingsOpen = ref(false)
|
||||
@@ -20,10 +19,16 @@ export const useSettings = defineStore('settings', () => {
|
||||
auto: false,
|
||||
})
|
||||
|
||||
const programs = createResource({
|
||||
url: 'lms.lms.utils.get_programs',
|
||||
auto: false,
|
||||
})
|
||||
|
||||
return {
|
||||
activeTab,
|
||||
isSettingsOpen,
|
||||
isCommandPaletteOpen,
|
||||
activeTab,
|
||||
programs,
|
||||
settings,
|
||||
sidebarSettings,
|
||||
}
|
||||
|
||||
@@ -403,51 +403,177 @@ export function getUserTimezone() {
|
||||
}
|
||||
|
||||
export function getSidebarLinks() {
|
||||
let links = getSidebarItems()
|
||||
|
||||
links.forEach((link) => {
|
||||
link.items = link.items.filter((item) => {
|
||||
return item.condition ? item.condition() : true
|
||||
})
|
||||
})
|
||||
|
||||
links = links.filter((link) => {
|
||||
return link.items.length > 0
|
||||
})
|
||||
|
||||
return links
|
||||
}
|
||||
|
||||
const getSidebarItems = () => {
|
||||
const { userResource } = usersStore()
|
||||
const { settings } = useSettings()
|
||||
|
||||
return [
|
||||
{
|
||||
label: 'Search',
|
||||
icon: 'Search',
|
||||
to: 'Search',
|
||||
},
|
||||
{
|
||||
label: 'Courses',
|
||||
icon: 'BookOpen',
|
||||
to: 'Courses',
|
||||
activeFor: [
|
||||
'Courses',
|
||||
'CourseDetail',
|
||||
'Lesson',
|
||||
'CourseForm',
|
||||
'LessonForm',
|
||||
label: 'General',
|
||||
hideLabel: true,
|
||||
items: [
|
||||
{
|
||||
label: 'Home',
|
||||
icon: 'Home',
|
||||
to: 'Home',
|
||||
condition: () => {
|
||||
return userResource?.data
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Search',
|
||||
icon: 'Search',
|
||||
to: 'Search',
|
||||
condition: () => {
|
||||
return userResource?.data
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Notifications',
|
||||
icon: 'Bell',
|
||||
to: 'Notifications',
|
||||
condition: () => {
|
||||
return userResource?.data
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Batches',
|
||||
icon: 'Users',
|
||||
to: 'Batches',
|
||||
activeFor: ['Batches', 'BatchDetail', 'Batch', 'BatchForm'],
|
||||
label: 'Learning',
|
||||
hideLabel: true,
|
||||
items: [
|
||||
{
|
||||
label: 'Courses',
|
||||
icon: 'BookOpen',
|
||||
to: 'Courses',
|
||||
activeFor: [
|
||||
'Courses',
|
||||
'CourseDetail',
|
||||
'Lesson',
|
||||
'CourseForm',
|
||||
'LessonForm',
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Programs',
|
||||
icon: 'Route',
|
||||
to: 'Programs',
|
||||
activeFor: ['Programs', 'ProgramDetail'],
|
||||
await: true,
|
||||
condition: () => {
|
||||
return checkIfCanAddProgram()
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Batches',
|
||||
icon: 'Users',
|
||||
to: 'Batches',
|
||||
activeFor: ['Batches', 'BatchDetail', 'Batch', 'BatchForm'],
|
||||
},
|
||||
{
|
||||
label: 'Certifications',
|
||||
icon: 'GraduationCap',
|
||||
to: 'CertifiedParticipants',
|
||||
activeFor: ['CertifiedParticipants'],
|
||||
},
|
||||
{
|
||||
label: 'Jobs',
|
||||
icon: 'Briefcase',
|
||||
to: 'Jobs',
|
||||
activeFor: ['Jobs', 'JobDetail'],
|
||||
},
|
||||
{
|
||||
label: 'Statistics',
|
||||
icon: 'TrendingUp',
|
||||
to: 'Statistics',
|
||||
activeFor: ['Statistics'],
|
||||
},
|
||||
{
|
||||
label: 'Contact Us',
|
||||
icon: settings.data?.contact_us_url ? 'Headset' : 'Mail',
|
||||
to: settings.data?.contact_us_url
|
||||
? settings.data?.contact_us_url
|
||||
: settings.data?.contact_us_email,
|
||||
condition: () => {
|
||||
return (
|
||||
settings?.data?.contact_us_email ||
|
||||
settings?.data?.contact_us_url
|
||||
)
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Certifications',
|
||||
icon: 'GraduationCap',
|
||||
to: 'CertifiedParticipants',
|
||||
activeFor: ['CertifiedParticipants'],
|
||||
},
|
||||
{
|
||||
label: 'Jobs',
|
||||
icon: 'Briefcase',
|
||||
to: 'Jobs',
|
||||
activeFor: ['Jobs', 'JobDetail'],
|
||||
},
|
||||
{
|
||||
label: 'Statistics',
|
||||
icon: 'TrendingUp',
|
||||
to: 'Statistics',
|
||||
activeFor: ['Statistics'],
|
||||
label: 'Assessments',
|
||||
hideLabel: true,
|
||||
items: [
|
||||
{
|
||||
label: 'Quizzes',
|
||||
icon: 'CircleHelp',
|
||||
to: 'Quizzes',
|
||||
condition: () => {
|
||||
return isAdmin()
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Assignments',
|
||||
icon: 'Pencil',
|
||||
to: 'Assignments',
|
||||
condition: () => {
|
||||
return isAdmin()
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Programming Exercises',
|
||||
icon: 'Code',
|
||||
to: 'ProgrammingExercises',
|
||||
condition: () => {
|
||||
return isAdmin()
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
const isAdmin = () => {
|
||||
const { userResource } = usersStore()
|
||||
return (
|
||||
userResource?.data?.is_instructor ||
|
||||
userResource?.data?.is_moderator ||
|
||||
userResource.data?.is_evaluator
|
||||
)
|
||||
}
|
||||
|
||||
const checkIfCanAddProgram = () => {
|
||||
const { userResource } = usersStore()
|
||||
const { programs } = useSettings()
|
||||
if (!userResource.data) return false
|
||||
if (userResource?.data?.is_moderator || userResource?.data?.is_instructor) {
|
||||
return true
|
||||
}
|
||||
console.log('programs.data', programs.data)
|
||||
return (
|
||||
programs.data?.enrolled.length > 0 ||
|
||||
programs.data?.published.length > 0
|
||||
)
|
||||
}
|
||||
|
||||
export function getFormattedDateRange(
|
||||
startDate,
|
||||
endDate,
|
||||
|
||||
Reference in New Issue
Block a user