2020-11-01 18:36:00 +01:00
|
|
|
<template>
|
2022-01-16 18:05:12 +01:00
|
|
|
<header
|
2020-11-01 18:36:00 +01:00
|
|
|
:class="{'has-background': background}"
|
|
|
|
aria-label="main navigation"
|
|
|
|
class="navbar main-theme is-fixed-top"
|
|
|
|
>
|
2021-11-22 22:12:54 +01:00
|
|
|
<router-link :to="{name: 'home'}" class="logo-link">
|
2021-11-13 21:28:29 +01:00
|
|
|
<Logo width="164" height="48"/>
|
2021-11-13 15:16:14 +01:00
|
|
|
</router-link>
|
2021-11-13 21:28:29 +01:00
|
|
|
<MenuButton class="menu-button"/>
|
2021-11-13 15:16:14 +01:00
|
|
|
<div class="list-title" ref="listTitle" v-show="currentList.id">
|
2021-06-24 01:24:57 +02:00
|
|
|
<template v-if="currentList.id">
|
|
|
|
<h1
|
|
|
|
:style="{ 'opacity': currentList.title === '' ? '0': '1' }"
|
|
|
|
class="title">
|
2021-07-09 10:22:20 +02:00
|
|
|
{{ currentList.title === '' ? $t('misc.loading') : getListTitle(currentList) }}
|
2021-06-24 01:24:57 +02:00
|
|
|
</h1>
|
2021-01-30 17:17:04 +01:00
|
|
|
|
2021-06-24 01:24:57 +02:00
|
|
|
<list-settings-dropdown v-if="canWriteCurrentList && currentList.id !== -1" :list="currentList"/>
|
|
|
|
</template>
|
2020-11-01 18:36:00 +01:00
|
|
|
</div>
|
2021-01-30 17:17:04 +01:00
|
|
|
|
2020-11-01 18:36:00 +01:00
|
|
|
<div class="navbar-end">
|
|
|
|
<update/>
|
2021-05-30 20:30:08 +02:00
|
|
|
<a
|
|
|
|
@click="openQuickActions"
|
|
|
|
class="trigger-button pr-0"
|
2021-11-13 21:28:29 +01:00
|
|
|
v-shortcut="'Control+k'"
|
|
|
|
:title="$t('keyboardShortcuts.quickSearch')"
|
2021-05-30 20:30:08 +02:00
|
|
|
>
|
|
|
|
<icon icon="search"/>
|
|
|
|
</a>
|
2021-02-21 16:13:58 +01:00
|
|
|
<notifications/>
|
2020-11-01 18:36:00 +01:00
|
|
|
<div class="user">
|
2021-06-23 22:08:20 +02:00
|
|
|
<dropdown class="is-right" ref="usernameDropdown">
|
2021-08-19 19:55:13 +02:00
|
|
|
<template #trigger>
|
2021-01-30 17:17:04 +01:00
|
|
|
<x-button
|
2022-01-04 19:58:06 +01:00
|
|
|
variant="secondary"
|
2022-02-13 22:57:33 +01:00
|
|
|
:shadow="false"
|
|
|
|
>
|
|
|
|
<img :src="userAvatar" alt="" class="avatar" width="40" height="40"/>
|
2020-11-21 22:25:00 +01:00
|
|
|
<span class="username">{{ userInfo.name !== '' ? userInfo.name : userInfo.username }}</span>
|
2020-11-01 18:36:00 +01:00
|
|
|
<span class="icon is-small">
|
2021-01-17 18:57:57 +01:00
|
|
|
<icon icon="chevron-down"/>
|
|
|
|
</span>
|
|
|
|
</x-button>
|
2021-01-30 17:17:04 +01:00
|
|
|
</template>
|
|
|
|
|
2022-02-13 22:57:33 +01:00
|
|
|
<BaseButton
|
|
|
|
:to="{name: 'user.settings'}"
|
|
|
|
class="dropdown-item"
|
|
|
|
>
|
2021-06-24 01:24:57 +02:00
|
|
|
{{ $t('user.settings.title') }}
|
2022-02-13 22:57:33 +01:00
|
|
|
</BaseButton>
|
|
|
|
<BaseButton
|
|
|
|
v-if="imprintUrl"
|
2021-01-30 17:17:04 +01:00
|
|
|
:href="imprintUrl"
|
|
|
|
class="dropdown-item"
|
2022-02-13 22:57:33 +01:00
|
|
|
>
|
2021-06-24 01:24:57 +02:00
|
|
|
{{ $t('navigation.imprint') }}
|
2022-02-13 22:57:33 +01:00
|
|
|
</BaseButton>
|
|
|
|
<BaseButton
|
|
|
|
v-if="privacyPolicyUrl"
|
2021-01-30 17:17:04 +01:00
|
|
|
:href="privacyPolicyUrl"
|
|
|
|
class="dropdown-item"
|
2022-02-13 22:57:33 +01:00
|
|
|
>
|
2021-06-24 01:24:57 +02:00
|
|
|
{{ $t('navigation.privacy') }}
|
2022-02-13 22:57:33 +01:00
|
|
|
</BaseButton>
|
|
|
|
<BaseButton
|
|
|
|
@click="$store.commit('keyboardShortcutsActive', true)"
|
|
|
|
class="dropdown-item"
|
|
|
|
>
|
2021-06-24 01:24:57 +02:00
|
|
|
{{ $t('keyboardShortcuts.title') }}
|
2022-02-13 22:57:33 +01:00
|
|
|
</BaseButton>
|
|
|
|
<BaseButton
|
|
|
|
:to="{name: 'about'}"
|
|
|
|
class="dropdown-item"
|
|
|
|
>
|
2021-07-06 17:05:35 +02:00
|
|
|
{{ $t('about.title') }}
|
2022-02-13 22:57:33 +01:00
|
|
|
</BaseButton>
|
|
|
|
<BaseButton
|
|
|
|
@click="logout()"
|
|
|
|
class="dropdown-item"
|
|
|
|
>
|
2021-06-24 01:24:57 +02:00
|
|
|
{{ $t('user.auth.logout') }}
|
2022-02-13 22:57:33 +01:00
|
|
|
</BaseButton>
|
2021-01-30 17:17:04 +01:00
|
|
|
</dropdown>
|
2020-11-01 18:36:00 +01:00
|
|
|
</div>
|
|
|
|
</div>
|
2022-01-16 18:05:12 +01:00
|
|
|
</header>
|
2020-11-01 18:36:00 +01:00
|
|
|
</template>
|
|
|
|
|
2022-02-13 22:57:33 +01:00
|
|
|
<script setup langs="ts">
|
|
|
|
import {ref, computed, onMounted, nextTick} from 'vue'
|
|
|
|
import {useStore} from 'vuex'
|
|
|
|
import {useRouter} from 'vue-router'
|
|
|
|
|
|
|
|
import {QUICK_ACTIONS_ACTIVE} from '@/store/mutation-types'
|
2021-09-10 16:21:33 +02:00
|
|
|
import Rights from '@/models/constants/rights.json'
|
2022-02-13 22:57:33 +01:00
|
|
|
|
2021-07-25 15:27:15 +02:00
|
|
|
import Update from '@/components/home/update.vue'
|
|
|
|
import ListSettingsDropdown from '@/components/list/list-settings-dropdown.vue'
|
|
|
|
import Dropdown from '@/components/misc/dropdown.vue'
|
|
|
|
import Notifications from '@/components/notifications/notifications.vue'
|
2021-11-13 15:16:14 +01:00
|
|
|
import Logo from '@/components/home/Logo.vue'
|
2022-02-13 22:57:33 +01:00
|
|
|
import BaseButton from '@/components/base/BaseButton.vue'
|
2021-11-13 15:16:14 +01:00
|
|
|
import MenuButton from '@/components/home/MenuButton.vue'
|
2021-10-03 20:48:02 +02:00
|
|
|
|
2022-02-13 22:57:33 +01:00
|
|
|
const store = useStore()
|
|
|
|
|
|
|
|
const userInfo = computed(() => store.state.auth.info)
|
|
|
|
const userAvatar = computed(() => store.state.auth.avatarUrl)
|
|
|
|
const currentList = computed(() => store.state.currentList)
|
|
|
|
const background = computed(() => store.state.background)
|
|
|
|
const imprintUrl = computed(() => store.state.config.legal.imprintUrl)
|
|
|
|
const privacyPolicyUrl = computed(() => store.state.config.legal.privacyPolicyUrl)
|
|
|
|
const canWriteCurrentList = computed(() => store.state.currentList.maxRight > Rights.READ)
|
|
|
|
|
|
|
|
const usernameDropdown = ref()
|
|
|
|
const listTitle = ref()
|
|
|
|
onMounted(async () => {
|
|
|
|
await nextTick()
|
|
|
|
if (typeof usernameDropdown.value === 'undefined' || typeof listTitle.value === 'undefined') {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const usernameWidth = usernameDropdown.value.$el.clientWidth
|
|
|
|
listTitle.value.style.setProperty('--nav-username-width', `${usernameWidth}px`)
|
|
|
|
})
|
|
|
|
|
|
|
|
const router = useRouter()
|
|
|
|
function logout() {
|
|
|
|
store.dispatch('auth/logout')
|
|
|
|
router.push({name: 'user.login'})
|
|
|
|
}
|
2021-06-24 01:24:57 +02:00
|
|
|
|
2022-02-13 22:57:33 +01:00
|
|
|
function openQuickActions() {
|
|
|
|
store.commit(QUICK_ACTIONS_ACTIVE, true)
|
2020-11-01 18:36:00 +01:00
|
|
|
}
|
|
|
|
</script>
|
2021-10-18 14:21:02 +02:00
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
2021-10-18 14:33:23 +02:00
|
|
|
$vikunja-nav-logo-full-width: 164px;
|
2021-11-22 22:12:54 +01:00
|
|
|
$user-dropdown-width-mobile: 5rem;
|
|
|
|
|
|
|
|
$hamburger-menu-icon-spacing: 1rem;
|
|
|
|
$hamburger-menu-icon-width: 28px;
|
2021-10-18 14:33:23 +02:00
|
|
|
|
|
|
|
.navbar {
|
|
|
|
z-index: 4 !important;
|
2021-11-13 15:16:14 +01:00
|
|
|
}
|
2021-10-18 14:33:23 +02:00
|
|
|
|
2021-11-22 22:12:54 +01:00
|
|
|
.logo-link {
|
2021-11-13 15:16:14 +01:00
|
|
|
display: none;
|
2021-11-22 22:12:54 +01:00
|
|
|
padding: 0.5rem 0.75rem;
|
2021-11-13 15:16:14 +01:00
|
|
|
|
|
|
|
@media screen and (min-width: $tablet) {
|
|
|
|
align-self: stretch;
|
2021-10-18 14:33:23 +02:00
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
2021-11-13 15:16:14 +01:00
|
|
|
padding-left: 2rem;
|
|
|
|
margin-right: 1.5rem;
|
2021-10-18 14:33:23 +02:00
|
|
|
}
|
2021-11-13 15:16:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
.menu-button {
|
|
|
|
align-self: stretch;
|
|
|
|
margin-right: auto;
|
|
|
|
|
|
|
|
@media screen and (max-width: $tablet) {
|
|
|
|
margin-left: $hamburger-menu-icon-spacing;
|
2021-10-18 14:33:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.navbar.main-theme {
|
2021-11-22 22:12:54 +01:00
|
|
|
background: var(--site-background);
|
2021-10-18 14:33:23 +02:00
|
|
|
z-index: 5 !important;
|
|
|
|
justify-content: space-between;
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
@media screen and (max-width: $desktop) {
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
|
|
|
}
|
|
|
|
|
|
|
|
.title {
|
|
|
|
margin: 0;
|
|
|
|
font-size: 1.75rem;
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
overflow: hidden;
|
|
|
|
white-space: nowrap;
|
|
|
|
}
|
|
|
|
|
|
|
|
.navbar-end {
|
|
|
|
margin-left: 0;
|
|
|
|
align-items: center;
|
|
|
|
display: flex;
|
|
|
|
}
|
|
|
|
|
|
|
|
@media screen and (max-width: $tablet) {
|
|
|
|
.user {
|
|
|
|
width: $user-dropdown-width-mobile;
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
|
2021-10-20 14:33:36 +02:00
|
|
|
:deep(.dropdown-trigger) {
|
2021-10-18 14:33:23 +02:00
|
|
|
line-height: 1;
|
|
|
|
|
|
|
|
.button {
|
|
|
|
padding: 0 0.25rem;
|
|
|
|
height: 1rem;
|
|
|
|
|
|
|
|
.icon {
|
|
|
|
width: .5rem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.username {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.navbar {
|
|
|
|
// FIXME: notifications should provide a slot for the icon instead, so that we can style it as we want
|
2021-10-20 14:33:36 +02:00
|
|
|
:deep() {
|
2021-10-18 14:33:23 +02:00
|
|
|
.trigger-button {
|
|
|
|
cursor: pointer;
|
2021-11-22 22:12:54 +01:00
|
|
|
color: var(--grey-400);
|
2021-10-18 14:33:23 +02:00
|
|
|
padding: .5rem;
|
|
|
|
font-size: 1.25rem;
|
|
|
|
position: relative;
|
|
|
|
}
|
|
|
|
|
|
|
|
> * > .trigger-button {
|
|
|
|
width: $navbar-icon-width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.user {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
span {
|
|
|
|
font-family: $vikunja-font;
|
|
|
|
}
|
|
|
|
|
|
|
|
.avatar {
|
|
|
|
border-radius: 100%;
|
|
|
|
vertical-align: middle;
|
|
|
|
height: 40px;
|
2022-02-13 22:57:33 +01:00
|
|
|
margin-right: var(--button-padding-horizontal);
|
2021-10-18 14:33:23 +02:00
|
|
|
}
|
|
|
|
|
2021-10-20 14:33:36 +02:00
|
|
|
:deep(.dropdown-trigger .button) {
|
2021-10-18 14:33:23 +02:00
|
|
|
background: none;
|
|
|
|
|
|
|
|
&:focus:not(:active), &:active {
|
|
|
|
outline: none !important;
|
|
|
|
box-shadow: none !important;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-18 14:21:02 +02:00
|
|
|
.list-title {
|
2021-11-13 21:28:29 +01:00
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
$edit-icon-width: 1rem;
|
|
|
|
|
|
|
|
@media screen and (min-width: $tablet) {
|
|
|
|
// We need a fixed width for overflowing ellipsis to work
|
|
|
|
--nav-username-width: 0;
|
|
|
|
width: calc(100vw - #{$user-dropdown-width-mobile} - #{2 * $hamburger-menu-icon-spacing} - #{$hamburger-menu-icon-width} - #{$edit-icon-width} - #{2 * $navbar-icon-width} - #{$vikunja-nav-logo-full-width} - var(--nav-username-width));
|
|
|
|
}
|
|
|
|
|
|
|
|
@media screen and (max-width: $tablet) {
|
|
|
|
// We need a fixed width for overflowing ellipsis to work
|
|
|
|
width: calc(100vw - #{$user-dropdown-width-mobile} - #{2 * $hamburger-menu-icon-spacing} - #{$hamburger-menu-icon-width} - #{$edit-icon-width} - #{2 * $navbar-icon-width});
|
|
|
|
}
|
|
|
|
|
|
|
|
h1 {
|
|
|
|
margin: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
:deep(.dropdown-trigger) {
|
2021-11-22 22:12:54 +01:00
|
|
|
color: var(--grey-400);
|
2021-11-13 21:28:29 +01:00
|
|
|
margin-left: 1rem;
|
|
|
|
height: 1rem;
|
|
|
|
width: 1rem;
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
2021-10-18 14:21:02 +02:00
|
|
|
}
|
|
|
|
</style>
|