platypush/platypush/backend/http/webapp/src/components/Nav.vue

308 lines
5.9 KiB
Vue
Raw Normal View History

2020-11-30 20:57:00 +01:00
<template>
<nav :class="{collapsed: collapsed}">
<div class="toggler" @click="collapsed = !collapsed">
<i class="fas fa-bars" />
2020-12-14 02:13:55 +01:00
<span class="hostname" v-if="hostname" v-text="hostname" />
2020-11-30 20:57:00 +01:00
</div>
<ul class="plugins">
2020-12-26 15:03:12 +01:00
<li v-for="name in Object.keys(panels).sort()" :key="name" class="entry" :class="{selected: name === selectedPanel}"
:title="name" @click="onItemClick(name)">
<a :href="`/#${name}`">
2020-11-30 20:57:00 +01:00
<span class="icon">
<i :class="icons[name].class" v-if="icons[name]?.class" />
2021-02-08 02:04:59 +01:00
<img :src="icons[name].imgUrl" v-else-if="icons[name]?.imgUrl" alt="name"/>
2020-11-30 20:57:00 +01:00
<i class="fas fa-puzzle-piece" v-else />
</span>
2021-01-05 00:50:24 +01:00
<span class="name" v-if="!collapsed" v-text="name" />
2020-12-26 15:03:12 +01:00
</a>
</li>
</ul>
<ul class="footer">
<li :class="{selected: selectedPanel === 'settings'}" title="Settings" @click="onItemClick('settings')">
<!--suppress HtmlUnknownAnchorTarget -->
<a href="/#settings">
<span class="icon">
<i class="fa fa-cog" />
</span>
<span class="name" v-if="!collapsed">Settings</span>
</a>
</li>
<li title="Logout" @click="onItemClick('logout')">
<!--suppress HtmlUnknownTarget -->
<a href="/logout">
<span class="icon">
<i class="fas fa-sign-out-alt" />
</span>
<span class="name" v-if="!collapsed">Logout</span>
</a>
</li>
</ul>
2020-11-30 20:57:00 +01:00
</nav>
</template>
<script>
import icons from '@/assets/icons.json'
2020-12-14 02:13:55 +01:00
import Utils from "@/Utils";
2020-11-30 20:57:00 +01:00
export default {
name: "Nav",
emits: ['select'],
2020-12-14 02:13:55 +01:00
mixins: [Utils],
2020-11-30 20:57:00 +01:00
props: {
panels: {
type: Object,
required: true,
},
selectedPanel: {
type: String,
},
hostname: {
type: String,
},
},
2020-12-03 00:59:35 +01:00
methods: {
2020-12-14 02:13:55 +01:00
onItemClick(name) {
this.$emit('select', name)
2020-12-31 01:36:02 +01:00
this.collapsed = true
2020-12-14 02:13:55 +01:00
},
2020-12-03 00:59:35 +01:00
},
2020-11-30 20:57:00 +01:00
data() {
return {
2020-12-09 21:16:07 +01:00
collapsed: true,
2020-11-30 20:57:00 +01:00
icons: icons,
host: null,
}
},
2020-12-14 02:13:55 +01:00
mounted() {
if (this.isMobile() && !this.$root.$route.hash.length)
this.collapsed = false
},
2020-11-30 20:57:00 +01:00
}
</script>
<!--suppress SassScssResolvedByNameOnly -->
<style lang="scss" scoped>
$toggler-height: 2em;
$footer-collapsed-height: 4em;
2021-02-19 22:55:31 +01:00
$footer-expanded-height: 7.5em;
2020-11-30 20:57:00 +01:00
nav {
2020-12-14 02:13:55 +01:00
@media screen and (max-width: $tablet) {
width: 100%;
height: 100vh;
background: $nav-bg;
color: $nav-fg;
box-shadow: $nav-box-shadow-main;
&:not(.collapsed) {
position: absolute;
top: 0;
left: 0;
z-index: 5;
2020-12-14 02:13:55 +01:00
}
}
@media screen and (min-width: $tablet) {
width: calc(16em - 2vw);
2020-12-14 02:13:55 +01:00
height: 100%;
overflow: auto;
background: $nav-bg;
color: $nav-fg;
box-shadow: $nav-box-shadow-main;
2020-12-26 15:03:12 +01:00
margin-right: 2px;
2020-12-14 02:13:55 +01:00
}
2020-11-30 20:57:00 +01:00
@media screen and (min-width: $desktop) {
width: 16em;
}
2020-11-30 20:57:00 +01:00
li {
2021-02-19 22:55:31 +01:00
border: $nav-entry-border;
2020-11-30 20:57:00 +01:00
cursor: pointer;
2020-12-14 02:13:55 +01:00
list-style: none;
2020-11-30 20:57:00 +01:00
2020-12-03 00:59:35 +01:00
a {
display: block;
color: $nav-fg;
padding: 1em 0.5em;
2020-12-03 00:59:35 +01:00
&:hover {
color: $nav-fg;
}
}
2020-11-30 20:57:00 +01:00
&:hover {
background: $nav-entry-hover-bg;
}
&.selected {
background: $nav-entry-selected-bg;
}
2021-02-14 21:08:29 +01:00
.name {
margin-left: 0.5em;
}
2020-11-30 20:57:00 +01:00
.icon {
margin-right: 0.5em;
}
}
.toggler {
width: 100%;
display: flex;
2021-02-19 22:55:31 +01:00
background: $nav-toggler-bg;
2020-11-30 20:57:00 +01:00
font-size: 1.5em;
cursor: pointer;
2021-02-19 22:55:31 +01:00
padding: 0.6em;
2020-12-14 02:13:55 +01:00
align-items: center;
2021-02-19 22:55:31 +01:00
box-shadow: $nav-toggler-shadow;
2020-12-14 02:13:55 +01:00
}
.hostname {
font-size: 0.7em;
margin-top: -0.2em;
2020-11-30 20:57:00 +01:00
2020-12-14 02:13:55 +01:00
@media screen and (min-width: $tablet) {
2020-11-30 20:57:00 +01:00
margin-left: 1em;
}
2020-12-14 02:13:55 +01:00
@media screen and (max-width: $tablet) {
text-align: right;
margin-right: 0.25em;
flex-grow: 1;
}
2020-11-30 20:57:00 +01:00
}
.plugins {
2021-02-19 22:55:31 +01:00
height: calc(100% - #{$toggler-height} - #{$footer-expanded-height} - 1.4em);
overflow: auto;
}
.footer {
height: $footer-expanded-height;
2021-02-19 22:55:31 +01:00
background: $nav-footer-bg;
padding: 0;
margin: 0;
}
ul {
li {
.icon {
margin-right: 0;
& img {
width: 1.25em;
height: 1.25em;
}
}
}
}
2020-11-30 20:57:00 +01:00
&.collapsed {
2020-12-26 15:03:12 +01:00
display: flex;
flex-direction: column;
2020-12-14 02:13:55 +01:00
@media screen and (min-width: $tablet) {
width: 2.5em;
min-width: unset;
max-width: unset;
2020-12-26 15:03:12 +01:00
background: $nav-collapsed-bg;
2020-12-14 02:13:55 +01:00
color: $nav-collapsed-fg;
box-shadow: $nav-box-shadow-collapsed;
.hostname {
display: none;
}
}
@media screen and (max-width: $tablet) {
height: auto;
}
2020-11-30 20:57:00 +01:00
a {
color: $nav-collapsed-fg;
2020-12-03 00:59:35 +01:00
padding: 0.25em 0;
2020-11-30 20:57:00 +01:00
&:hover {
color: $nav-collapsed-fg;
}
}
.toggler {
height: $toggler-height;
2021-02-19 22:55:31 +01:00
background: none;
2020-11-30 20:57:00 +01:00
text-align: center;
2021-02-19 22:55:31 +01:00
padding: 0.4em;
box-shadow: none;
}
.footer {
height: $footer-collapsed-height;
2021-02-19 22:55:31 +01:00
background: none;
padding: 0;
margin-bottom: .5em;
}
@media screen and (max-width: $tablet) {
.footer {
display: none;
}
}
2020-12-26 15:03:12 +01:00
ul {
display: flex;
flex-direction: column;
justify-content: center;
2021-02-19 22:55:31 +01:00
height: calc(100% - #{$toggler-height} - #{$footer-collapsed-height});
overflow: hidden;
&.plugins {
@media screen and (min-width: $tablet) and (max-width: $desktop - 1px) {
justify-content: left;
margin: 2em 0;
}
}
&:hover {
overflow: auto;
}
2020-11-30 20:57:00 +01:00
2020-12-26 15:03:12 +01:00
li {
2021-02-19 22:55:31 +01:00
border: none;
2020-12-26 15:03:12 +01:00
padding: 0;
text-align: center;
2020-11-30 20:57:00 +01:00
2020-12-26 15:03:12 +01:00
&.selected,
&:hover {
border-radius: 1em;
margin: 0 0.2em;
}
2020-11-30 20:57:00 +01:00
2020-12-26 15:03:12 +01:00
&.selected {
background: $nav-entry-collapsed-selected-bg;
}
2020-11-30 20:57:00 +01:00
2020-12-26 15:03:12 +01:00
&:hover {
background: $nav-entry-collapsed-hover-bg;
}
2020-12-14 02:13:55 +01:00
2020-12-26 15:03:12 +01:00
.icon {
margin-right: 0;
}
@media screen and (max-width: $tablet) {
display: none;
}
2020-12-14 02:13:55 +01:00
}
2020-11-30 20:57:00 +01:00
}
}
}
</style>