refactor: new project structure
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<div class="sidebar">
|
||||
<SidebarHeader/>
|
||||
<SidebarForm/>
|
||||
<nav class="sidebar-nav">
|
||||
<div slot="header"></div>
|
||||
<ul class="nav">
|
||||
<template v-for="(item, index) in navItems">
|
||||
<template v-if="item.title">
|
||||
<SidebarNavTitle :name="item.name" :classes="item.class" :wrapper="item.wrapper"/>
|
||||
</template>
|
||||
<template v-else-if="item.divider">
|
||||
<SidebarNavDivider :classes="item.class"/>
|
||||
</template>
|
||||
<template v-else-if="item.label">
|
||||
<SidebarNavLabel :name="item.name" :url="item.url" :icon="item.icon" :label="item.label" :classes="item.class"/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="item.children">
|
||||
<!-- First level dropdown -->
|
||||
<SidebarNavDropdown :name="item.name" :url="item.url" :icon="item.icon">
|
||||
<template v-for="(childL1, index) in item.children">
|
||||
<template v-if="childL1.children">
|
||||
<!-- Second level dropdown -->
|
||||
<SidebarNavDropdown :name="childL1.name" :url="childL1.url" :icon="childL1.icon">
|
||||
<li class="nav-item" v-for="(childL2, index) in childL1.children">
|
||||
<SidebarNavLink :name="childL2.name" :url="childL2.url" :icon="childL2.icon" :badge="childL2.badge" :variant="item.variant"/>
|
||||
</li>
|
||||
</SidebarNavDropdown>
|
||||
</template>
|
||||
<template v-else>
|
||||
<SidebarNavItem :classes="item.class">
|
||||
<SidebarNavLink :name="childL1.name" :url="childL1.url" :icon="childL1.icon" :badge="childL1.badge" :variant="item.variant"/>
|
||||
</SidebarNavItem>
|
||||
</template>
|
||||
</template>
|
||||
</SidebarNavDropdown>
|
||||
</template>
|
||||
<template v-else>
|
||||
<SidebarNavItem :classes="item.class">
|
||||
<SidebarNavLink :name="item.name" :url="item.url" :icon="item.icon" :badge="item.badge" :variant="item.variant"/>
|
||||
</SidebarNavItem>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</ul>
|
||||
<slot></slot>
|
||||
</nav>
|
||||
<SidebarFooter/>
|
||||
<SidebarMinimizer/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import SidebarFooter from './SidebarFooter'
|
||||
import SidebarForm from './SidebarForm'
|
||||
import SidebarHeader from './SidebarHeader'
|
||||
import SidebarMinimizer from './SidebarMinimizer'
|
||||
import SidebarNavDivider from './SidebarNavDivider'
|
||||
import SidebarNavDropdown from './SidebarNavDropdown'
|
||||
import SidebarNavLink from './SidebarNavLink'
|
||||
import SidebarNavTitle from './SidebarNavTitle'
|
||||
import SidebarNavItem from './SidebarNavItem'
|
||||
import SidebarNavLabel from './SidebarNavLabel'
|
||||
export default {
|
||||
name: 'sidebar',
|
||||
props: {
|
||||
navItems: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
components: {
|
||||
SidebarFooter,
|
||||
SidebarForm,
|
||||
SidebarHeader,
|
||||
SidebarMinimizer,
|
||||
SidebarNavDivider,
|
||||
SidebarNavDropdown,
|
||||
SidebarNavLink,
|
||||
SidebarNavTitle,
|
||||
SidebarNavItem,
|
||||
SidebarNavLabel
|
||||
},
|
||||
methods: {
|
||||
handleClick (e) {
|
||||
e.preventDefault()
|
||||
e.target.parentElement.classList.toggle('open')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css">
|
||||
.nav-link {
|
||||
cursor:pointer;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<!-- <div class="sidebar-footer"></div> -->
|
||||
</template>
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'sidebar-footer'
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<!-- <div class="sidebar-form"></div> -->
|
||||
</template>
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'sidebar-form'
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<!-- <div class="sidebar-header"></div> -->
|
||||
</template>
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'sidebar-header'
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<button class="sidebar-minimizer" type="button" @click="sidebarMinimize();brandMinimize()"></button>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'sidebar-minimizer',
|
||||
methods: {
|
||||
sidebarMinimize () {
|
||||
document.body.classList.toggle('sidebar-minimized')
|
||||
},
|
||||
brandMinimize () {
|
||||
document.body.classList.toggle('brand-minimized')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<li :class="classList"></li>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'sidebar-nav-divider',
|
||||
props: {
|
||||
classes: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
classList () {
|
||||
return [
|
||||
'divider',
|
||||
...this.itemClasses
|
||||
]
|
||||
},
|
||||
itemClasses () {
|
||||
return this.classes ? this.classes.split(' ') : ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<router-link tag="li" class="nav-item nav-dropdown" :to="url" disabled>
|
||||
<div class="nav-link nav-dropdown-toggle" @click="handleClick"><i :class="icon"></i> {{name}}</div>
|
||||
<ul class="nav-dropdown-items">
|
||||
<slot></slot>
|
||||
</ul>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClick (e) {
|
||||
e.preventDefault()
|
||||
e.target.parentElement.classList.toggle('open')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<li :class="classList" @click="hideMobile">
|
||||
<slot></slot>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'sidebar-nav-item',
|
||||
props: {
|
||||
classes: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
classList () {
|
||||
return [
|
||||
'nav-item',
|
||||
...this.itemClasses
|
||||
]
|
||||
},
|
||||
itemClasses () {
|
||||
return this.classes ? this.classes.split(' ') : ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
hideMobile () {
|
||||
if (document.body.classList.contains('sidebar-mobile-show')) {
|
||||
document.body.classList.toggle('sidebar-mobile-show')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<SidebarNavItem :classes="classList.navItem">
|
||||
<a :class="classList.navLink" :href="url"><i :class="classList.icon"></i> {{name}}</a>
|
||||
</SidebarNavItem>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SidebarNavItem from './SidebarNavItem'
|
||||
import SidebarNavLink from './SidebarNavLink'
|
||||
export default {
|
||||
name: 'sidebar-nav-label',
|
||||
components: {
|
||||
SidebarNavItem,
|
||||
SidebarNavLink
|
||||
},
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
default: '#'
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: 'fa fa-circle'
|
||||
},
|
||||
classes: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
label: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
classList () {
|
||||
const classes = {
|
||||
navItem: ['hidden-cn', ...this.getClasses(this.classes)].join(' '),
|
||||
navLink: 'nav-label',
|
||||
icon: [
|
||||
this.icon ? this.icon : 'fa fa-circle',
|
||||
this.label.variant ? `text-${this.label.variant}` : '',
|
||||
this.label.class ? this.label.class : ''
|
||||
].join(' ')
|
||||
}
|
||||
return classes
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getClasses (classes) {
|
||||
return classes ? classes.split(' ') : []
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div v-if="isExternalLink">
|
||||
<a :href="url" :class="classList">
|
||||
<i :class="icon"></i> {{name}}
|
||||
<b-badge v-if="badge && badge.text" :variant="badge.variant">{{badge.text}}</b-badge>
|
||||
</a>
|
||||
</div>
|
||||
<div v-else>
|
||||
<router-link :to="url" :class="classList">
|
||||
<i :class="icon"></i> {{name}}
|
||||
<b-badge v-if="badge && badge.text" :variant="badge.variant">{{badge.text}}</b-badge>
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'sidebar-nav-link',
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
badge: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
variant: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
classes: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
classList () {
|
||||
return [
|
||||
'nav-link',
|
||||
this.linkVariant,
|
||||
...this.itemClasses
|
||||
]
|
||||
},
|
||||
linkVariant () {
|
||||
return this.variant ? `nav-link-${this.variant}` : ''
|
||||
},
|
||||
itemClasses () {
|
||||
return this.classes ? this.classes.split(' ') : []
|
||||
},
|
||||
isExternalLink () {
|
||||
if (this.url.substring(0, 4) === 'http') {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<li :class="classList">
|
||||
<template v-if="wrapper && wrapper.element">
|
||||
<component v-bind:is="wrapper.element" v-bind="wrapper.attributes">
|
||||
{{name}}
|
||||
</component>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{name}}
|
||||
</template>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
classes: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
wrapper: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
classList () {
|
||||
return [
|
||||
'nav-title',
|
||||
...this.itemClasses
|
||||
]
|
||||
},
|
||||
itemClasses () {
|
||||
return this.classes ? this.classes.split(' ') : ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user