wikijs-fork/client/themes/default/components/nav-sidebar.vue

218 lines
7.0 KiB
Vue
Raw Normal View History

2018-09-23 04:14:01 +00:00
<template lang="pug">
div
2020-04-24 19:46:38 +00:00
.pa-3.d-flex(v-if='navMode === `MIXED`', :class='$vuetify.theme.dark ? `grey darken-5` : `blue darken-3`')
v-btn(depressed, :color='$vuetify.theme.dark ? `grey darken-4` : `blue darken-2`', style='min-width:0;', @click='goHome')
2020-02-02 21:26:44 +00:00
v-icon(size='20') mdi-home
2020-04-24 19:46:38 +00:00
v-btn.ml-3(v-if='currentMode === `custom`', depressed, :color='$vuetify.theme.dark ? `grey darken-4` : `blue darken-2`', style='flex: 1 1 100%;', @click='switchMode(`browse`)')
2020-02-02 21:26:44 +00:00
v-icon(left) mdi-file-tree
.body-2.text-none {{$t('common:sidebar.browse')}}
2020-04-24 19:46:38 +00:00
v-btn.ml-3(v-else-if='currentMode === `browse`', depressed, :color='$vuetify.theme.dark ? `grey darken-4` : `blue darken-2`', style='flex: 1 1 100%;', @click='switchMode(`custom`)')
2020-02-02 21:26:44 +00:00
v-icon(left) mdi-navigation
.body-2.text-none {{$t('common:sidebar.mainMenu')}}
2020-02-02 21:26:44 +00:00
v-divider
//-> Custom Navigation
v-list.py-2(v-if='currentMode === `custom`', dense, :class='color', :dark='dark')
template(v-for='item of items')
v-list-item(
2020-05-08 22:48:07 +00:00
v-if='item.k === `link`'
:href='item.t'
:target='item.y === `externalblank` ? `_blank` : `_self`'
:rel='item.y === `externalblank` ? `noopener` : ``'
)
2020-02-10 03:55:53 +00:00
v-list-item-avatar(size='24', tile)
2020-05-08 22:48:07 +00:00
v-icon {{ item.c }}
v-list-item-title {{ item.l }}
v-divider.my-2(v-else-if='item.k === `divider`')
v-subheader.pl-4(v-else-if='item.k === `header`') {{ item.l }}
2020-02-02 21:26:44 +00:00
//-> Browse
v-list.py-2(v-else-if='currentMode === `browse`', dense, :class='color', :dark='dark')
template(v-if='currentParent.id > 0')
v-list-item(v-for='(item, idx) of parents', :key='`parent-` + item.id', @click='fetchBrowseItems(item)', style='min-height: 30px;')
v-list-item-avatar(size='18', :style='`padding-left: ` + (idx * 8) + `px; width: auto; margin: 0 5px 0 0;`')
v-icon(small) mdi-folder-open
v-list-item-title {{ item.title }}
v-divider.mt-2
2020-04-26 18:19:44 +00:00
v-list-item.mt-2(v-if='currentParent.pageId > 0', :href='`/` + currentParent.path', :key='`directorypage-` + currentParent.id', :input-value='path === currentParent.path')
v-list-item-avatar(size='24')
v-icon mdi-text-box
v-list-item-title {{ currentParent.title }}
v-subheader.pl-4 {{$t('common:sidebar.currentDirectory')}}
2020-02-02 21:26:44 +00:00
template(v-for='item of currentItems')
v-list-item(v-if='item.isFolder', :key='`childfolder-` + item.id', @click='fetchBrowseItems(item)')
v-list-item-avatar(size='24')
v-icon mdi-folder
v-list-item-title {{ item.title }}
v-list-item(v-else, :href='`/` + item.path', :key='`childpage-` + item.id', :input-value='path === item.path')
v-list-item-avatar(size='24')
2020-04-12 22:05:48 +00:00
v-icon mdi-text-box
2020-02-02 21:26:44 +00:00
v-list-item-title {{ item.title }}
2018-09-23 04:14:01 +00:00
</template>
<script>
2020-02-02 21:26:44 +00:00
import _ from 'lodash'
import gql from 'graphql-tag'
import { get } from 'vuex-pathify'
/* global siteLangs */
2018-09-23 04:14:01 +00:00
export default {
props: {
color: {
type: String,
default: 'primary'
},
dark: {
type: Boolean,
default: true
2019-08-04 17:54:23 +00:00
},
items: {
type: Array,
default: () => []
2020-02-02 21:26:44 +00:00
},
2020-04-13 01:19:22 +00:00
navMode: {
type: String,
default: 'MIXED'
2018-09-23 04:14:01 +00:00
}
},
data() {
2020-02-02 21:26:44 +00:00
return {
2020-04-13 19:54:10 +00:00
currentMode: 'custom',
2020-02-02 21:26:44 +00:00
currentItems: [],
currentParent: {
id: 0,
title: '/ (root)'
},
2020-04-12 22:05:48 +00:00
parents: [],
loadedCache: []
2020-02-02 21:26:44 +00:00
}
},
computed: {
path: get('page/path'),
locale: get('page/locale')
},
methods: {
switchMode (mode) {
this.currentMode = mode
window.localStorage.setItem('navPref', mode)
2020-04-12 22:05:48 +00:00
if (mode === `browse` && this.loadedCache.length < 1) {
this.loadFromCurrentPath()
2020-02-02 21:26:44 +00:00
}
},
async fetchBrowseItems (item) {
this.$store.commit(`loadingStart`, 'browse-load')
if (!item) {
item = this.currentParent
2020-04-12 22:05:48 +00:00
}
if (this.loadedCache.indexOf(item.id) < 0) {
this.currentItems = []
}
if (item.id === 0) {
this.parents = []
2020-02-02 21:26:44 +00:00
} else {
2020-04-12 22:05:48 +00:00
const flushRightIndex = _.findIndex(this.parents, ['id', item.id])
if (flushRightIndex >= 0) {
this.parents = _.take(this.parents, flushRightIndex)
}
if (this.parents.length < 1) {
2020-02-02 21:26:44 +00:00
this.parents.push(this.currentParent)
}
2020-04-12 22:05:48 +00:00
this.parents.push(item)
2020-02-02 21:26:44 +00:00
}
2020-04-12 22:05:48 +00:00
this.currentParent = item
2020-02-02 21:26:44 +00:00
const resp = await this.$apollo.query({
query: gql`
2020-04-12 22:05:48 +00:00
query ($parent: Int, $locale: String!) {
2020-02-02 21:26:44 +00:00
pages {
2020-04-12 22:05:48 +00:00
tree(parent: $parent, mode: ALL, locale: $locale) {
2020-02-02 21:26:44 +00:00
id
path
title
isFolder
pageId
parent
}
}
}
`,
fetchPolicy: 'cache-first',
variables: {
parent: item.id,
locale: this.locale
}
})
2020-04-12 22:05:48 +00:00
this.loadedCache = _.union(this.loadedCache, [item.id])
2020-02-02 21:26:44 +00:00
this.currentItems = _.get(resp, 'data.pages.tree', [])
2020-04-12 22:05:48 +00:00
this.$store.commit(`loadingStop`, 'browse-load')
},
async loadFromCurrentPath() {
this.$store.commit(`loadingStart`, 'browse-load')
const resp = await this.$apollo.query({
query: gql`
query ($path: String, $locale: String!) {
pages {
tree(path: $path, mode: ALL, locale: $locale, includeAncestors: true) {
id
path
title
isFolder
pageId
parent
}
}
}
`,
fetchPolicy: 'cache-first',
variables: {
path: this.path,
locale: this.locale
}
})
const items = _.get(resp, 'data.pages.tree', [])
const curPage = _.find(items, ['pageId', this.$store.get('page/id')])
if (!curPage) {
console.warn('Could not find current page in page tree listing!')
return
}
let curParentId = curPage.parent
let invertedAncestors = []
while (curParentId) {
const curParent = _.find(items, ['id', curParentId])
if (!curParent) {
break
}
invertedAncestors.push(curParent)
curParentId = curParent.parent
}
this.parents = [this.currentParent, ...invertedAncestors.reverse()]
this.currentParent = _.last(this.parents)
this.loadedCache = [curPage.parent]
this.currentItems = _.filter(items, ['parent', curPage.parent])
2020-02-02 21:26:44 +00:00
this.$store.commit(`loadingStop`, 'browse-load')
},
goHome () {
window.location.assign(siteLangs.length > 0 ? `/${this.locale}/home` : '/')
2020-02-02 21:26:44 +00:00
}
},
mounted () {
this.currentParent.title = `/ ${this.$t('common:sidebar.root')}`
2020-04-13 19:54:10 +00:00
if (this.navMode === 'TREE') {
this.currentMode = 'browse'
2020-04-25 21:45:59 +00:00
} else if (this.navMode === 'STATIC') {
this.currentMode = 'custom'
2020-04-13 19:54:10 +00:00
} else {
this.currentMode = window.localStorage.getItem('navPref') || 'custom'
}
if (this.currentMode === 'browse') {
this.loadFromCurrentPath()
2020-02-02 21:26:44 +00:00
}
2018-09-23 04:14:01 +00:00
}
}
</script>