Move side navigation to separate component

This commit is contained in:
kolaente 2020-11-01 17:03:06 +01:00
parent 3877218980
commit 49dc828abe
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
5 changed files with 193 additions and 154 deletions

View File

@ -13,159 +13,22 @@
:style="{'background-image': `url(${background})`}"
class="app-container"
>
<div :class="{'is-active': menuActive}" class="namespace-container">
<div class="menu top-menu">
<router-link :to="{name: 'home'}" class="logo">
<img alt="Vikunja" src="/images/logo-full.svg"/>
</router-link>
<ul class="menu-list">
<li>
<router-link :to="{ name: 'home'}">
<span class="icon">
<icon icon="calendar"/>
</span>
Overview
</router-link>
</li>
<li>
<router-link :to="{ name: 'tasks.range', params: {type: 'week'}}">
<span class="icon">
<icon icon="calendar-week"/>
</span>
Next Week
</router-link>
</li>
<li>
<router-link :to="{ name: 'tasks.range', params: {type: 'month'}}">
<span class="icon">
<icon :icon="['far', 'calendar-alt']"/>
</span>
Next Month
</router-link>
</li>
<li>
<router-link :to="{ name: 'teams.index'}">
<span class="icon">
<icon icon="users"/>
</span>
Teams
</router-link>
</li>
<li>
<router-link :to="{ name: 'namespaces.index'}">
<span class="icon">
<icon icon="layer-group"/>
</span>
Namespaces & Lists
</router-link>
</li>
<li>
<router-link :to="{ name: 'labels.index'}">
<span class="icon">
<icon icon="tags"/>
</span>
Labels
</router-link>
</li>
</ul>
</div>
<aside class="menu namespaces-lists">
<template v-for="n in namespaces">
<div :key="n.id">
<router-link
:to="{name: 'namespace.edit', params: {id: n.id} }"
class="nsettings"
v-if="n.id > 0"
v-tooltip.right="'Settings'">
<span class="icon">
<icon icon="cog"/>
</span>
</router-link>
<router-link
:key="n.id + 'list.create'"
:to="{ name: 'list.create', params: { id: n.id} }"
class="nsettings"
v-if="n.id > 0"
v-tooltip="'Add a new list in the ' + n.title + ' namespace'">
<span class="icon">
<icon icon="plus"/>
</span>
</router-link>
<label
:for="n.id + 'checker'"
class="menu-label"
v-tooltip="n.title + ' (' + n.lists.length + ')'">
<span class="name">
<span
:style="{ backgroundColor: n.hexColor }"
class="color-bubble"
v-if="n.hexColor !== ''">
</span>
{{ n.title }} ({{ n.lists.length }})
</span>
</label>
</div>
<input
:id="n.id + 'checker'"
:key="n.id + 'checker'"
checked="checked"
class="checkinput"
type="checkbox"/>
<div :key="n.id + 'child'" class="more-container">
<ul class="menu-list can-be-hidden">
<template v-for="l in n.lists">
<!-- This is a bit ugly but vue wouldn't want to let me filter this - probably because the lists
are nested inside of the namespaces makes it a lot harder.-->
<li :key="l.id" v-if="!l.isArchived">
<router-link
class="list-menu-link"
:class="{'router-link-exact-active': currentList.id === l.id}"
:to="{ name: 'list.index', params: { listId: l.id} }"
tag="span"
>
<span
:style="{ backgroundColor: l.hexColor }"
class="color-bubble"
v-if="l.hexColor !== ''">
</span>
<span class="list-menu-title">
{{ l.title }}
</span>
<span
:class="{'is-favorite': l.isFavorite}"
@click.stop="toggleFavoriteList(l)"
class="favorite">
<icon icon="star" v-if="l.isFavorite"/>
<icon :icon="['far', 'star']" v-else/>
</span>
</router-link>
</li>
</template>
</ul>
<label :for="n.id + 'checker'" class="hidden-hint">
Show hidden lists ({{ n.lists.length }})...
</label>
</div>
</template>
</aside>
<a class="menu-bottom-link" href="https://vikunja.io" target="_blank">Powered by Vikunja</a>
</div>
<navigation/>
<div
:class="[
{
'fullpage-overlay': fullpage,
'is-menu-enabled': menuActive,
},
$route.name,
]"
{
'fullpage-overlay': fullpage,
'is-menu-enabled': menuActive,
},
$route.name,
]"
class="app-content"
>
<a @click="$store.commit('menuActive', false)" class="mobile-overlay" v-if="menuActive"></a>
<transition name="fade">
<router-view/>
</transition>
<a @click="keyboardShortcutsActive = true" class="keyboard-shortcuts-button">
<a @click="$store.commit('keyboardShortcutsActive', true)" class="keyboard-shortcuts-button">
<icon icon="keyboard"/>
</a>
</div>
@ -223,7 +86,7 @@
</div>
<transition name="fade">
<keyboard-shortcuts @close="keyboardShortcutsActive = false" v-if="keyboardShortcutsActive"/>
<keyboard-shortcuts v-if="keyboardShortcutsActive"/>
</transition>
</div>
</template>
@ -236,14 +99,16 @@ import authTypes from './models/authTypes'
import Rights from './models/rights.json'
import Notification from './components/misc/notification'
import {CURRENT_LIST, IS_FULLPAGE, MENU_ACTIVE, ONLINE} from './store/mutation-types'
import {CURRENT_LIST, IS_FULLPAGE, KEYBOARD_SHORTCUTS_ACTIVE, MENU_ACTIVE, ONLINE} from './store/mutation-types'
import KeyboardShortcuts from './components/misc/keyboard-shortcuts'
import topNavigation from '@/components/home/topNavigation'
import TopNavigation from '@/components/home/topNavigation'
import Navigation from '@/components/home/navigation'
export default {
name: 'app',
components: {
topNavigation,
Navigation,
TopNavigation,
KeyboardShortcuts,
Notification,
},
@ -251,7 +116,6 @@ export default {
return {
currentDate: new Date(),
authTypes: authTypes,
keyboardShortcutsActive: false,
}
},
beforeMount() {
@ -297,7 +161,7 @@ export default {
created() {
// Make sure to always load the home route when running with electron
if(this.$route.fullPath.endsWith('frontend/index.html')) {
if (this.$route.fullPath.endsWith('frontend/index.html')) {
this.$router.push({name: 'home'})
}
@ -354,6 +218,7 @@ export default {
privacyPolicyUrl: state => state.config.legal.privacyPolicyUrl,
canWriteCurrentList: state => state.currentList.maxRight > Rights.READ,
menuActive: MENU_ACTIVE,
keyboardShortcutsActive: KEYBOARD_SHORTCUTS_ACTIVE,
}),
methods: {
logout() {

View File

@ -0,0 +1,158 @@
<template>
<div :class="{'is-active': menuActive}" class="namespace-container">
<div class="menu top-menu">
<router-link :to="{name: 'home'}" class="logo">
<img alt="Vikunja" src="/images/logo-full.svg"/>
</router-link>
<ul class="menu-list">
<li>
<router-link :to="{ name: 'home'}">
<span class="icon">
<icon icon="calendar"/>
</span>
Overview
</router-link>
</li>
<li>
<router-link :to="{ name: 'tasks.range', params: {type: 'week'}}">
<span class="icon">
<icon icon="calendar-week"/>
</span>
Next Week
</router-link>
</li>
<li>
<router-link :to="{ name: 'tasks.range', params: {type: 'month'}}">
<span class="icon">
<icon :icon="['far', 'calendar-alt']"/>
</span>
Next Month
</router-link>
</li>
<li>
<router-link :to="{ name: 'teams.index'}">
<span class="icon">
<icon icon="users"/>
</span>
Teams
</router-link>
</li>
<li>
<router-link :to="{ name: 'namespaces.index'}">
<span class="icon">
<icon icon="layer-group"/>
</span>
Namespaces & Lists
</router-link>
</li>
<li>
<router-link :to="{ name: 'labels.index'}">
<span class="icon">
<icon icon="tags"/>
</span>
Labels
</router-link>
</li>
</ul>
</div>
<aside class="menu namespaces-lists">
<template v-for="n in namespaces">
<div :key="n.id">
<router-link
:to="{name: 'namespace.edit', params: {id: n.id} }"
class="nsettings"
v-if="n.id > 0"
v-tooltip.right="'Settings'">
<span class="icon">
<icon icon="cog"/>
</span>
</router-link>
<router-link
:key="n.id + 'list.create'"
:to="{ name: 'list.create', params: { id: n.id} }"
class="nsettings"
v-if="n.id > 0"
v-tooltip="'Add a new list in the ' + n.title + ' namespace'">
<span class="icon">
<icon icon="plus"/>
</span>
</router-link>
<label
:for="n.id + 'checker'"
class="menu-label"
v-tooltip="n.title + ' (' + n.lists.length + ')'">
<span class="name">
<span
:style="{ backgroundColor: n.hexColor }"
class="color-bubble"
v-if="n.hexColor !== ''">
</span>
{{ n.title }} ({{ n.lists.length }})
</span>
</label>
</div>
<input
:id="n.id + 'checker'"
:key="n.id + 'checker'"
checked="checked"
class="checkinput"
type="checkbox"/>
<div :key="n.id + 'child'" class="more-container">
<ul class="menu-list can-be-hidden">
<template v-for="l in n.lists">
<!-- This is a bit ugly but vue wouldn't want to let me filter this - probably because the lists
are nested inside of the namespaces makes it a lot harder.-->
<li :key="l.id" v-if="!l.isArchived">
<router-link
class="list-menu-link"
:class="{'router-link-exact-active': currentList.id === l.id}"
:to="{ name: 'list.index', params: { listId: l.id} }"
tag="span"
>
<span
:style="{ backgroundColor: l.hexColor }"
class="color-bubble"
v-if="l.hexColor !== ''">
</span>
<span class="list-menu-title">
{{ l.title }}
</span>
<span
:class="{'is-favorite': l.isFavorite}"
@click.stop="toggleFavoriteList(l)"
class="favorite">
<icon icon="star" v-if="l.isFavorite"/>
<icon :icon="['far', 'star']" v-else/>
</span>
</router-link>
</li>
</template>
</ul>
<label :for="n.id + 'checker'" class="hidden-hint">
Show hidden lists ({{ n.lists.length }})...
</label>
</div>
</template>
</aside>
<a class="menu-bottom-link" href="https://vikunja.io" target="_blank">Powered by Vikunja</a>
</div>
</template>
<script>
import {mapState} from 'vuex'
import {CURRENT_LIST, IS_FULLPAGE, MENU_ACTIVE} from '@/store/mutation-types'
export default {
name: 'navigation',
computed: mapState({
fullpage: IS_FULLPAGE,
namespaces(state) {
return state.namespaces.namespaces.filter(n => !n.isArchived)
},
currentList: CURRENT_LIST,
background: 'background',
menuActive: MENU_ACTIVE,
}),
}
</script>

View File

@ -88,11 +88,13 @@
</template>
<script>
import {KEYBOARD_SHORTCUTS_ACTIVE} from '@/store/mutation-types'
export default {
name: 'keyboard-shortcuts',
methods: {
close() {
this.$emit('close')
this.$store.commit(KEYBOARD_SHORTCUTS_ACTIVE, false)
},
},
}

View File

@ -1,6 +1,15 @@
import Vue from 'vue'
import Vuex from 'vuex'
import {CURRENT_LIST, ERROR_MESSAGE, HAS_TASKS, IS_FULLPAGE, LOADING, MENU_ACTIVE, ONLINE} from './mutation-types'
import {
CURRENT_LIST,
ERROR_MESSAGE,
HAS_TASKS,
IS_FULLPAGE,
KEYBOARD_SHORTCUTS_ACTIVE,
LOADING,
MENU_ACTIVE,
ONLINE,
} from './mutation-types'
import config from './modules/config'
import auth from './modules/auth'
import namespaces from './modules/namespaces'
@ -34,6 +43,7 @@ export const store = new Vuex.Store({
background: '',
hasTasks: false,
menuActive: true,
keyboardShortcutsActive: false,
},
mutations: {
[LOADING](state, loading) {
@ -103,6 +113,9 @@ export const store = new Vuex.Store({
},
toggleMenu(state) {
state.menuActive = !state.menuActive
}
},
[KEYBOARD_SHORTCUTS_ACTIVE](state, active) {
state.keyboardShortcutsActive = active
},
},
})

View File

@ -5,6 +5,7 @@ export const IS_FULLPAGE = 'isFullpage'
export const CURRENT_LIST = 'currentList'
export const HAS_TASKS = 'hasTasks'
export const MENU_ACTIVE = 'menuActive'
export const KEYBOARD_SHORTCUTS_ACTIVE = 'keyboardShortcutsActive'
export const CONFIG = 'config'
export const AUTH = 'auth'