Skip to content
Snippets Groups Projects
BaseLayout.vue 4.06 KiB
<template>
  <div>
    <v-navigation-drawer
      fixed
      clipped
      app
      permanent
      :mini-variant="mini"
    >
      <v-toolbar>
        <v-list>
          <v-list-tile>
            <v-list-tile-action v-if="mini">
              <v-btn icon @click.native.stop="mini = !mini">
                <v-icon>chevron_right</v-icon>
              </v-btn>
            </v-list-tile-action>
            <v-list-tile-content
              class="title"
            >
              <slot name="header"></slot>
            </v-list-tile-content>
            <v-list-tile-action v-if="!mini">
              <v-btn icon @click.native.stop="mini = !mini">
                <v-icon>chevron_left</v-icon>
              </v-btn>
            </v-list-tile-action>
          </v-list-tile>
        </v-list>
      </v-toolbar>
      <slot name="sidebar-content"></slot>
      <div class="sidebar-footer">
        <v-tooltip top style="min-width: 150px">
          <v-switch
            class="ml-3"
            slot="activator"
            :disabled="!darkModeUnlocked"
            v-model="darkMode" label="dark mode"/>
          <span v-if="darkModeUnlocked">Experimental: styling issues may occur!</span>
          <span v-else>You need to visit the feedback site below first!</span>
        </v-tooltip>
        <v-footer v-if="!mini" @click.native="logFeedbackClick">
          <v-spacer/>
          <a
            href="https://gitlab.gwdg.de/j.michal/grady/issues"
            target="_blank"
            class="feedback-link"
          >Give us Feedback!</a>
          <v-spacer/>
        </v-footer>
      </div>
    </v-navigation-drawer>
    <v-toolbar
      app
      clipped-left
      fixed
      dark
      color="indigo darken-4"
      class="grady-toolbar"
    >
      <v-toolbar-title>
        <router-link to="/home">
          <v-avatar>
            <img v-if="production" :src="productionBrandUrl"/>
            <img v-else src="../assets/brand.png"/>
          </v-avatar>
        </router-link>
      </v-toolbar-title>
      <span class="pl-2 grady-speak">{{ gradySpeak }}</span>
      <v-spacer/>
      <slot name="toolbar-center"/>
      <div class="toolbar-content">
        <v-menu bottom offset-y>
          <v-btn slot="activator" color="cyan" style="text-transform: none">
            {{ userRole }} | {{ username }} <v-icon>arrow_drop_down</v-icon>
          </v-btn>
          <user-options/>
        </v-menu>
      </div>
      <v-btn color="blue darken-1" to="/" @click.native="logout">Logout</v-btn>
      <slot name="toolbar-right"></slot>
    </v-toolbar>
  </div>
</template>

<script>
import { mapGetters, mapState } from 'vuex'
import {uiMut} from '@/store/modules/ui'
import { mapStateToComputedGetterSetter } from '@/util/helpers'
import UserOptions from '@/components/UserOptions'

export default {
  name: 'base-layout',
  components: {UserOptions},
  computed: {
    ...mapGetters([
      'gradySpeak'
    ]),
    ...mapState({
      username: state => state.authentication.user.username,
      userRole: state => state.authentication.user.role
    }),
    ...mapStateToComputedGetterSetter({
      pathPrefix: 'ui',
      items: [
        {
          name: 'darkMode',
          mutation: uiMut.SET_DARK_MODE
        },
        {
          name: 'darkModeUnlocked',
          mutation: uiMut.SET_DARK_MODE_UNLOCKED
        },
        {
          name: 'mini',
          path: 'sideBarCollapsed',
          mutation: uiMut.SET_SIDEBAR_COLLAPSED
        }
      ]
    }),
    production () {
      return process.env.NODE_ENV === 'production'
    },
    productionBrandUrl () {
      return `https://${window.location.host}/static/img/brand.png`
    }
  },
  methods: {
    logout () {
      this.$store.dispatch('logout')
    },
    logFeedbackClick () {
      this.darkModeUnlocked = true
    }
  }
}
</script>

<style scoped>
  .sidebar-footer {
    position: absolute;
    width: 100%;
    bottom: 0px;
  }

  .feedback-link {
    text-decoration: none;
    color: grey;
  }

  .toolbar-content {
    margin-left: auto;
  }

  .grady-toolbar {
    font-weight: bold;
  }

  .title {
    color: gray;
  }
</style>