1
0
forked from test/crm

refactor: app sidebar

This commit is contained in:
Shariq Ansari 2024-01-28 13:43:18 +05:30
parent 9ffe08a13b
commit ffe24b9c0d
3 changed files with 89 additions and 80 deletions

View File

@ -3,81 +3,50 @@
class="flex h-full flex-col justify-between transition-all duration-300 ease-in-out"
:class="isSidebarCollapsed ? 'w-12' : 'w-56'"
>
<div class="flex flex-1 flex-col overflow-hidden">
<div>
<UserDropdown class="p-2" :isCollapsed="isSidebarCollapsed" />
<div class="flex flex-col overflow-y-auto">
<SidebarLink
v-for="link in links"
:icon="link.icon"
:label="link.label"
:to="link.to"
:isCollapsed="isSidebarCollapsed"
class="mx-2 my-0.5"
/>
</div>
<div
v-if="isSidebarCollapsed && getPublicViews().length"
class="mx-2 my-2 h-1 border-b"
/>
<div
v-if="getPublicViews().length"
class="px-3 text-base text-gray-600 transition-all duration-300 ease-in-out"
:class="
isSidebarCollapsed
? 'ml-0 h-0 overflow-hidden opacity-0'
: 'ml-2 h-7 w-auto opacity-100 mt-4'
"
>
Public Views
</div>
<div v-if="getPublicViews().length" class="flex flex-col overflow-y-auto">
<SidebarLink
v-for="publicView in getPublicViews()"
:icon="
h(getIcon(publicView.route_name), {
class: 'h-4.5 w-4.5 text-gray-700',
})
"
:label="publicView.label"
:to="{
name: publicView.route_name,
query: { view: publicView.name },
}"
:isCollapsed="isSidebarCollapsed"
class="mx-2 my-0.5"
/>
</div>
<div
v-if="isSidebarCollapsed && getPinnedViews().length"
class="mx-2 my-2 h-1 border-b"
/>
<div
v-if="getPinnedViews().length"
class="px-3 text-base text-gray-600 transition-all duration-300 ease-in-out"
:class="
isSidebarCollapsed
? 'ml-0 h-0 overflow-hidden opacity-0'
: 'ml-2 h-7 w-auto opacity-100 mt-4'
"
>
Pinned Views
</div>
<div v-if="getPinnedViews().length" class="flex flex-col overflow-y-auto">
<SidebarLink
v-for="pinnedView in getPinnedViews()"
:icon="
h(getIcon(pinnedView.route_name), {
class: 'h-4.5 w-4.5 text-gray-700',
})
"
:label="pinnedView.label"
:to="{
name: pinnedView.route_name,
query: { view: pinnedView.name },
}"
:isCollapsed="isSidebarCollapsed"
class="mx-2 my-0.5"
</div>
<div class="flex-1 overflow-y-auto">
<div v-for="view in allViews" :key="view.label">
<div
v-if="!view.hideLabel && isSidebarCollapsed && view.views?.length"
class="mx-2 my-2 h-1 border-b"
/>
<Section
:label="view.name"
:hideLabel="view.hideLabel"
:isOpened="view.opened"
>
<template #header="{ opened, hide, toggle }">
<div
v-if="!hide"
class="flex cursor-pointer gap-1.5 px-1 text-sm font-medium text-gray-600 transition-all duration-300 ease-in-out"
:class="
isSidebarCollapsed
? 'ml-0 h-0 overflow-hidden opacity-0'
: 'ml-2 mt-4 h-7 w-auto opacity-100'
"
@click="toggle()"
>
<FeatherIcon
name="chevron-right"
class="h-4 text-gray-900 transition-all duration-300 ease-in-out"
:class="{ 'rotate-90': opened }"
/>
{{ view.name }}
</div>
</template>
<nav class="flex flex-col">
<SidebarLink
v-for="link in view.views"
:icon="link.icon"
:label="link.label"
:to="link.to"
:isCollapsed="isSidebarCollapsed"
class="mx-2 my-0.5"
/>
</nav>
</Section>
</div>
</div>
<SidebarLink
@ -99,6 +68,7 @@
</template>
<script setup>
import Section from '@/components/Section.vue'
import EmailIcon from '@/components/Icons/EmailIcon.vue'
import PinIcon from '@/components/Icons/PinIcon.vue'
import UserDropdown from '@/components/UserDropdown.vue'
@ -112,9 +82,10 @@ import CollapseSidebar from '@/components/Icons/CollapseSidebar.vue'
import SidebarLink from '@/components/SidebarLink.vue'
import { viewsStore } from '@/stores/views'
import { useStorage } from '@vueuse/core'
import { h } from 'vue'
import { computed } from 'vue'
const { getPinnedViews, getPublicViews } = viewsStore()
const isSidebarCollapsed = useStorage('sidebar_is_collapsed', false)
const links = [
{
@ -154,6 +125,40 @@ const links = [
},
]
const allViews = computed(() => {
return [
{
name: 'All Views',
hideLabel: true,
opened: true,
views: links,
},
{
name: 'PULIC VIEWS',
opened: true,
views: parseView(getPublicViews()),
},
{
name: 'PINNED VIEWS',
opened: true,
views: parseView(getPinnedViews()),
},
]
})
function parseView(views) {
return views.map((view) => {
return {
label: view.label,
icon: getIcon(view.route_name),
to: {
name: view.route_name,
query: { view: view.name },
},
}
})
}
function getIcon(routeName) {
switch (routeName) {
case 'Leads':
@ -172,6 +177,4 @@ function getIcon(routeName) {
return PinIcon
}
}
const isSidebarCollapsed = useStorage('sidebar_is_collapsed', false)
</script>

View File

@ -1,6 +1,6 @@
<template>
<slot name="header" v-bind="{ opened, open, close, toggle }">
<div class="flex items-center justify-between">
<slot name="header" v-bind="{ opened, hide, open, close, toggle }">
<div v-if="!hide" class="flex items-center justify-between">
<div
class="flex h-7 max-w-fit cursor-pointer items-center gap-2 pl-2 pr-3 text-base font-semibold leading-5"
@click="toggle()"
@ -35,6 +35,10 @@ const props = defineProps({
type: String,
default: '',
},
hideLabel: {
type: Boolean,
default: false,
},
isOpened: {
type: Boolean,
default: true,
@ -51,5 +55,7 @@ function open() {
function close() {
opened.value = false
}
let opened = ref(props.isOpened)
let hide = ref(props.hideLabel)
</script>

View File

@ -11,12 +11,12 @@
<Tooltip :text="label" placement="right">
<slot name="icon">
<span class="grid h-5 w-6 flex-shrink-0 place-items-center">
<component :is="icon" class="h-4.5 w-4.5 text-gray-700" />
<component :is="icon" class="h-4 w-4 text-gray-700" />
</span>
</slot>
</Tooltip>
<span
class="flex-shrink-0 text-base duration-300 ease-in-out"
class="flex-shrink-0 text-sm duration-300 ease-in-out"
:class="
isCollapsed
? 'ml-0 w-0 overflow-hidden opacity-0'