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="flex h-full flex-col justify-between transition-all duration-300 ease-in-out"
:class="isSidebarCollapsed ? 'w-12' : 'w-56'" :class="isSidebarCollapsed ? 'w-12' : 'w-56'"
> >
<div class="flex flex-1 flex-col overflow-hidden"> <div>
<UserDropdown class="p-2" :isCollapsed="isSidebarCollapsed" /> <UserDropdown class="p-2" :isCollapsed="isSidebarCollapsed" />
<div class="flex flex-col overflow-y-auto"> </div>
<SidebarLink <div class="flex-1 overflow-y-auto">
v-for="link in links" <div v-for="view in allViews" :key="view.label">
:icon="link.icon" <div
:label="link.label" v-if="!view.hideLabel && isSidebarCollapsed && view.views?.length"
:to="link.to" class="mx-2 my-2 h-1 border-b"
: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"
/> />
<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>
</div> </div>
<SidebarLink <SidebarLink
@ -99,6 +68,7 @@
</template> </template>
<script setup> <script setup>
import Section from '@/components/Section.vue'
import EmailIcon from '@/components/Icons/EmailIcon.vue' import EmailIcon from '@/components/Icons/EmailIcon.vue'
import PinIcon from '@/components/Icons/PinIcon.vue' import PinIcon from '@/components/Icons/PinIcon.vue'
import UserDropdown from '@/components/UserDropdown.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 SidebarLink from '@/components/SidebarLink.vue'
import { viewsStore } from '@/stores/views' import { viewsStore } from '@/stores/views'
import { useStorage } from '@vueuse/core' import { useStorage } from '@vueuse/core'
import { h } from 'vue' import { computed } from 'vue'
const { getPinnedViews, getPublicViews } = viewsStore() const { getPinnedViews, getPublicViews } = viewsStore()
const isSidebarCollapsed = useStorage('sidebar_is_collapsed', false)
const links = [ 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) { function getIcon(routeName) {
switch (routeName) { switch (routeName) {
case 'Leads': case 'Leads':
@ -172,6 +177,4 @@ function getIcon(routeName) {
return PinIcon return PinIcon
} }
} }
const isSidebarCollapsed = useStorage('sidebar_is_collapsed', false)
</script> </script>

View File

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

View File

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