2020-07-06 19:08:34 +02:00
|
|
|
<template>
|
2020-07-15 16:39:24 +02:00
|
|
|
<div id="app" class="container">
|
2020-10-08 23:58:09 +02:00
|
|
|
<!-- HEADER -->
|
2020-07-15 16:39:24 +02:00
|
|
|
<header>
|
|
|
|
<b-navbar>
|
2020-10-12 15:21:01 +02:00
|
|
|
<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-10-08 23:58:09 +02:00
|
|
|
|
2020-07-15 16:39:24 +02:00
|
|
|
<b-navbar-nav class="ml-auto">
|
|
|
|
<li class="nav-item">
|
2020-10-08 23:58:09 +02:00
|
|
|
<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-10-08 23:58:09 +02:00
|
|
|
|
2020-07-15 16:39:24 +02:00
|
|
|
<li class="nav-item" v-show="connected">
|
2020-10-08 23:58:09 +02:00
|
|
|
<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
|
|
|
|
2020-10-08 23:58:09 +02:00
|
|
|
<!-- MAIN -->
|
2021-02-11 16:58:57 +01:00
|
|
|
<view-lock-overlay>
|
2020-10-09 18:02:22 +02:00
|
|
|
<breadcrumb />
|
|
|
|
|
|
|
|
<main id="main">
|
2020-11-03 19:10:30 +01:00
|
|
|
<!-- The `key` on router-view make sure that if a link points to a page that
|
|
|
|
use the same component as the previous one, it will be refreshed -->
|
2020-10-09 18:02:22 +02:00
|
|
|
<transition v-if="transitions" :name="transitionName">
|
2020-11-03 19:10:30 +01:00
|
|
|
<router-view class="animated" :key="$route.fullPath" />
|
2020-10-09 18:02:22 +02:00
|
|
|
</transition>
|
2020-11-03 19:10:30 +01:00
|
|
|
<router-view v-else class="static" :key="$route.fullPath" />
|
2020-10-09 18:02:22 +02:00
|
|
|
</main>
|
2021-02-11 16:58:57 +01:00
|
|
|
</view-lock-overlay>
|
2020-10-12 15:21:01 +02:00
|
|
|
|
2021-02-11 16:58:57 +01:00
|
|
|
<!-- HISTORY CONSOLE -->
|
|
|
|
<history-console />
|
2020-10-12 15:21:01 +02:00
|
|
|
|
2020-10-08 23:58:09 +02:00
|
|
|
<!-- FOOTER -->
|
2020-10-13 15:26:31 +02:00
|
|
|
<footer class="py-3 mt-auto">
|
2020-07-15 16:39:24 +02:00
|
|
|
<nav>
|
2020-09-27 15:18:07 +02:00
|
|
|
<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">
|
2020-09-27 15:18:07 +02:00
|
|
|
<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">
|
2020-09-27 15:18:07 +02:00
|
|
|
<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">
|
2020-09-27 15:18:07 +02:00
|
|
|
<icon iname="heart" /> {{ $t('footer.donate') }}
|
2020-07-15 16:39:24 +02:00
|
|
|
</b-nav-item>
|
2020-11-06 14:44:15 +01:00
|
|
|
|
|
|
|
<b-nav-text
|
|
|
|
v-if="yunohost" id="yunohost-version" class="ml-md-auto text-center"
|
|
|
|
v-html="$t('footer_version', yunohost)"
|
|
|
|
/>
|
2020-07-15 16:39:24 +02:00
|
|
|
</b-nav>
|
|
|
|
</nav>
|
|
|
|
</footer>
|
|
|
|
</div>
|
2020-07-06 19:08:34 +02:00
|
|
|
</template>
|
2020-07-07 13:54:01 +02:00
|
|
|
|
2020-07-10 18:42:40 +02:00
|
|
|
<script>
|
2020-08-27 18:30:45 +02:00
|
|
|
import { mapGetters } from 'vuex'
|
2020-07-10 18:42:40 +02:00
|
|
|
|
2021-02-11 16:58:57 +01:00
|
|
|
import { HistoryConsole, ViewLockOverlay } from '@/views/_partials'
|
2020-10-09 18:02:22 +02:00
|
|
|
|
2020-07-10 18:42:40 +02:00
|
|
|
export default {
|
2020-07-15 16:39:24 +02:00
|
|
|
name: 'App',
|
2020-08-28 18:54:18 +02:00
|
|
|
|
2021-02-11 16:58:57 +01:00
|
|
|
components: {
|
|
|
|
HistoryConsole,
|
|
|
|
ViewLockOverlay
|
|
|
|
},
|
|
|
|
|
2020-10-12 15:21:01 +02:00
|
|
|
data () {
|
|
|
|
return {
|
2020-10-13 15:26:31 +02:00
|
|
|
transitionName: null
|
2020-10-12 15:21:01 +02:00
|
|
|
}
|
|
|
|
},
|
2020-10-08 23:58:09 +02:00
|
|
|
|
2020-07-15 16:39:24 +02:00
|
|
|
computed: {
|
2020-10-12 15:21:01 +02:00
|
|
|
...mapGetters(['connected', 'yunohost', 'transitions', 'waiting'])
|
2020-10-08 23:58:09 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
watch: {
|
|
|
|
// Set the css class to animate the components transition
|
|
|
|
'$route' (to, from) {
|
2020-10-12 15:21:01 +02:00
|
|
|
if (!this.transitions || from.name === null) return
|
2020-10-08 23:58:09 +02:00
|
|
|
// 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-08-28 18:54:18 +02:00
|
|
|
|
2020-07-15 16:39:24 +02:00
|
|
|
methods: {
|
|
|
|
async logout () {
|
2020-09-27 15:18:07 +02:00
|
|
|
this.$store.dispatch('LOGOUT')
|
2020-07-15 16:39:24 +02:00
|
|
|
}
|
|
|
|
},
|
2020-08-28 18:54:18 +02:00
|
|
|
|
|
|
|
// This hook is only triggered at page first load
|
2020-12-16 15:09:19 +01:00
|
|
|
created () {
|
2020-08-28 18:54:18 +02:00
|
|
|
// From this hook the value of `connected` always come from the localStorage.
|
2020-09-27 15:18:07 +02:00
|
|
|
// 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
|
|
|
}
|
2020-12-16 15:09:19 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
mounted () {
|
2021-09-24 20:24:58 +02:00
|
|
|
// Unlock copypasta on log view
|
|
|
|
const copypastaCode = ['ArrowDown', 'ArrowDown', 'ArrowUp', 'ArrowUp']
|
|
|
|
let copypastastep = 0
|
|
|
|
document.addEventListener('keydown', ({ key }) => {
|
|
|
|
if (key === copypastaCode[copypastastep++]) {
|
|
|
|
if (copypastastep === copypastaCode.length) {
|
2021-10-01 18:07:08 +02:00
|
|
|
document.getElementsByClassName('unselectable').forEach((element) => element.classList.remove('unselectable'))
|
2021-09-24 20:24:58 +02:00
|
|
|
copypastastep = 0
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
copypastastep = 0
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2020-12-16 15:09:19 +01:00
|
|
|
// Konamicode ;P
|
|
|
|
const konamiCode = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a']
|
2021-09-24 20:24:58 +02:00
|
|
|
let konamistep = 0
|
2020-12-16 15:09:19 +01:00
|
|
|
document.addEventListener('keydown', ({ key }) => {
|
2021-09-24 20:24:58 +02:00
|
|
|
if (key === konamiCode[konamistep++]) {
|
|
|
|
if (konamistep === konamiCode.length) {
|
2020-12-16 15:09:19 +01:00
|
|
|
this.$store.commit('SET_SPINNER', 'nyancat')
|
2021-09-24 20:24:58 +02:00
|
|
|
konamistep = 0
|
2020-12-16 15:09:19 +01:00
|
|
|
}
|
|
|
|
} else {
|
2021-09-24 20:24:58 +02:00
|
|
|
konamistep = 0
|
2020-12-16 15:09:19 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
// April fools easter egg ;)
|
|
|
|
const today = new Date()
|
|
|
|
if (today.getDate() === 1 && today.getMonth() + 1 === 4) {
|
|
|
|
this.$store.commit('SET_SPINNER', 'magikarp')
|
|
|
|
}
|
2020-07-15 16:39:24 +02:00
|
|
|
}
|
2020-07-10 18:42:40 +02:00
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
2020-07-07 13:54:01 +02:00
|
|
|
<style lang="scss">
|
2020-10-12 15:21:01 +02:00
|
|
|
// Global import of Bootstrap and custom styles
|
2020-07-07 13:54:01 +02:00
|
|
|
@import '@/scss/main.scss';
|
2020-10-12 15:21:01 +02:00
|
|
|
</style>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
2020-10-13 15:26:31 +02:00
|
|
|
// generic style for <html>, <body> and <#app> is in `scss/main.scss`
|
2020-10-12 15:21:01 +02:00
|
|
|
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
|
|
|
}
|
2020-10-08 23:58:09 +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;
|
|
|
|
}
|
|
|
|
}
|
2020-10-12 15:21:01 +02:00
|
|
|
|
|
|
|
#console {
|
|
|
|
// Allows the console to be tabbed before the footer links while remaining visually
|
|
|
|
// the last element of the page
|
|
|
|
order: 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
footer {
|
2021-04-06 16:57:06 +02:00
|
|
|
border-top: $thin-border;
|
2020-10-12 15:21:01 +02:00
|
|
|
font-size: $font-size-sm;
|
|
|
|
margin-top: 2rem;
|
|
|
|
|
|
|
|
.nav-item {
|
|
|
|
& + .nav-item a::before {
|
|
|
|
content: "•";
|
|
|
|
width: 1rem;
|
|
|
|
display: inline-block;
|
|
|
|
margin-left: -1.15rem;
|
|
|
|
}
|
|
|
|
&:first-child {
|
|
|
|
margin-left: -1rem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-07-07 13:54:01 +02:00
|
|
|
</style>
|