yunohost-admin/app/src/App.vue

231 lines
5.6 KiB
Vue
Raw Normal View History

2020-07-06 19:08:34 +02:00
<template>
2020-07-15 16:39:24 +02:00
<div id="app" class="container">
<!-- HEADER -->
2020-07-15 16:39:24 +02:00
<header>
<b-navbar>
<b-navbar-brand
:to="{ name: 'home' }" :disabled="waiting"
exact exact-active-class="active"
>
2020-07-15 16:39:24 +02:00
<img alt="Yunohost logo" src="./assets/logo.png">
</b-navbar-brand>
2020-07-15 16:39:24 +02:00
<b-navbar-nav class="ml-auto">
<li class="nav-item">
<b-button
href="/yunohost/sso"
variant="primary" size="sm" block
2020-07-15 16:39:24 +02:00
>
{{ $t('user_interface_link') }} <icon iname="user" />
</b-button>
</li>
2020-07-15 16:39:24 +02:00
<li class="nav-item" v-show="connected">
<b-button
@click.prevent="logout"
variant="outline-dark" block size="sm"
2020-07-15 16:39:24 +02:00
>
{{ $t('logout') }} <icon iname="sign-out" />
</b-button>
</li>
</b-navbar-nav>
</b-navbar>
</header>
2020-07-07 18:56:12 +02:00
<!-- MAIN -->
<api-wait-overlay>
<breadcrumb />
<main id="main">
<transition v-if="transitions" :name="transitionName">
<router-view class="animated" />
</transition>
<router-view v-else class="static" />
</main>
</api-wait-overlay>
<!-- CONSOLE/HISTORY -->
<ynh-console @height-changed="consoleHeight = $event" class="mt-auto" />
<!-- FOOTER -->
<footer :style="'padding-bottom: ' + consoleHeight + 'px;'">
2020-07-15 16:39:24 +02:00
<nav>
<b-nav class="justify-content-center">
2020-07-15 16:39:24 +02:00
<b-nav-item href="https://yunohost.org/docs" target="_blank" link-classes="text-secondary">
<icon iname="book" /> {{ $t('footer.documentation') }}
2020-07-15 16:39:24 +02:00
</b-nav-item>
<b-nav-item href="https://yunohost.org/help" target="_blank" link-classes="text-secondary">
<icon iname="life-ring" /> {{ $t('footer.help') }}
2020-07-15 16:39:24 +02:00
</b-nav-item>
<b-nav-item href="https://donate.yunohost.org/" target="_blank" link-classes="text-secondary">
<icon iname="heart" /> {{ $t('footer.donate') }}
2020-07-15 16:39:24 +02:00
</b-nav-item>
<i18n
v-if="yunohost" path="footer.version" tag="b-nav-text"
id="yunohost-version" class="ml-md-auto text-center"
2020-07-15 16:39:24 +02:00
>
<template v-slot:ynh>
<b-link href="https://yunohost.org">
YunoHost
</b-link>
</template>
<template v-slot:version>
{{ yunohost.version }}
2020-07-15 16:39:24 +02:00
</template>
<template v-slot:repo>
{{ yunohost.repo }}
2020-07-15 16:39:24 +02:00
</template>
</i18n>
</b-nav>
</nav>
</footer>
</div>
2020-07-06 19:08:34 +02:00
</template>
<script>
import { mapGetters } from 'vuex'
import ApiWaitOverlay from '@/components/ApiWaitOverlay'
import YnhConsole from '@/components/YnhConsole'
export default {
2020-07-15 16:39:24 +02:00
name: 'App',
data () {
return {
transitionName: null,
// Value used to add padding to the footer so the opened console never hides content
consoleHeight: 0
}
},
2020-07-15 16:39:24 +02:00
computed: {
...mapGetters(['connected', 'yunohost', 'transitions', 'waiting'])
},
watch: {
// Set the css class to animate the components transition
'$route' (to, from) {
if (!this.transitions || from.name === null) return
// Use the breadcrumb array length as a direction indicator
const toDepth = to.meta.breadcrumb.length
const fromDepth = from.meta.breadcrumb.length
this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
}
2020-07-15 16:39:24 +02:00
},
2020-07-15 16:39:24 +02:00
methods: {
async logout () {
this.$store.dispatch('LOGOUT')
2020-07-15 16:39:24 +02:00
}
},
components: {
ApiWaitOverlay,
YnhConsole
},
// This hook is only triggered at page first load
2020-07-15 16:39:24 +02:00
async created () {
// From this hook the value of `connected` always come from the localStorage.
// This state may be `true` but session may have expired, by querying
// yunohost infos, api may respond with `Unauthorized` in which case the `connected`
// state will be automaticly reseted and user will be prompt with the login view.
if (this.connected) {
this.$store.dispatch('GET_YUNOHOST_INFOS')
2020-07-15 16:39:24 +02:00
}
}
}
</script>
<style lang="scss">
// Global import of Bootstrap and custom styles
@import '@/scss/main.scss';
</style>
<style lang="scss" scoped>
2020-07-07 18:56:12 +02:00
::v-deep#app {
display: flex;
flex-direction: column;
height: 100%;
}
header {
2020-07-16 14:49:34 +02:00
border-bottom: $thin-border;
2020-07-15 16:39:24 +02:00
padding-top: 1rem;
margin-bottom: 1rem;
2020-07-07 18:56:12 +02:00
2020-07-15 16:39:24 +02:00
.navbar {
padding: 1rem 0;
2020-07-07 18:56:12 +02:00
2020-07-15 16:39:24 +02:00
img {
width: 70px;
}
2020-07-07 18:56:12 +02:00
2020-07-15 16:39:24 +02:00
.navbar-nav {
flex-direction: column;
2020-07-07 18:56:12 +02:00
2020-07-15 16:39:24 +02:00
li {
margin: .2rem 0;
}
2020-07-07 18:56:12 +02:00
}
2020-07-15 16:39:24 +02:00
}
2020-07-07 18:56:12 +02:00
}
main {
position: relative;
// Routes transition
.animated {
transition: all .15s ease-in-out;
}
.slide-left-enter, .slide-right-leave-active {
position: absolute;
width: 100%;
top: 0;
transform: translate(100vw, 0);
}
.slide-left-leave-active, .slide-right-enter {
position: absolute;
width: 100%;
top: 0;
transform: translate(-100vw, 0);
}
// hack to hide last transition provoqued by the <router-view> element change
// while disabling the transitions in ToolWebAdmin
.static ~ .animated {
display: none;
}
}
#console {
// Allows the console to be tabbed before the footer links while remaining visually
// the last element of the page
order: 3;
}
footer {
border-top: 1px solid #eee;
font-size: $font-size-sm;
margin-top: 2rem;
padding-bottom: 3rem;
.nav {
padding: 1rem 0 3rem 0;
}
.nav-item {
& + .nav-item a::before {
content: "•";
width: 1rem;
display: inline-block;
margin-left: -1.15rem;
}
&:first-child {
margin-left: -1rem;
}
}
}
</style>