summaryrefslogblamecommitdiffstats
path: root/webapp/src/components/DashboardPage.vue
blob: c32e87dc8aefcc20e48e8cab559ca6ad76648b61 (plain) (tree)
1
2
3
4
5
6
7
8
9


         
                                     
                   



                           
                                   
                       






                                
                                                                     
 
                        
                                   

                                           
                                            



                          
     


                                                                                                       
                                                                                                                                                     
                  

                                                                                                                  
                                                      




                                                                                                       
                   
                                                                              
              
            

                          








                                                       
                                  

                                                                          
                                   

                            
                                                                                                                         
 
                           
 
                                                                                                                                                                           
 




                                                                                      
 
                                                                               


                                      
                                                                                  


                                                                                      
                    
                             
                                   
                                                                                   
                     
                  

















                                                                       



                     
 
                                             
                                                       



           
                                                         
                                                      
                                                          
                                                

                                                                        
                                                        
                                                    


                        


                                                    

                                                      

     
               
                    


                          

            
                                      
                                                                
                                                                


             
                              
                            
                                          
                                          
                                                           
                                                                

          


                                      












                                                                     
                                          
                     
                                                                                

                                             
               
                                                                      
                                                   
                                   
                            



              
                                                                  
                                    





              



                         
       
                           


                   

                     




                    
              













                          
                              





                    





                          
        
<i18n>
{
  "en": {
    "title": "Boot Selection Server",
    "user": "User",
    "settings": "Settings",
    "logout": "Logout"
  },
  "de": {
    "title": "Boot Auswahl Server",
    "user": "Benutzer",
    "settings": "Einstellungen",
    "logout": "Abmelden"
  }
}
</i18n>

<template>
  <v-app :class="{ 'no-animation': settings.noAnimations }" class="">

    <v-navigation-drawer
      class="drawer non-selectable"
      persistent
      :mini-variant="desktop && drawerMini"
      :clipped="settings.clipped && desktop"
      v-model="drawerOpen"
      fixed
      width="250"
      app
    >
      <div class="tutorial-element label-bottom tutorial-border" style="--label-number: '1'">
        <div class="drawer-header grey darken-4 hidden-lg-and-up"><img src="@/assets/logo.svg" /></div>
        <div v-for="category in categories" :key="category.name">
          <div class="dashboard-category text--secondary body-2">{{ desktop && drawerMini ? '' : $t('$dashboardCategories.' + category.name) }}</div>
          <v-list>
            <v-list-item ripple v-for="module in category.modules" :key="module.name" :to="{ name: module.name }">
              <v-list-item-action>
                <v-icon v-html="module.icon"></v-icon>
              </v-list-item-action>
              <v-list-item-content>
                <v-list-item-title v-text="$t('$dashboardModules.' + module.name)"></v-list-item-title>
              </v-list-item-content>
            </v-list-item>
          </v-list>
          <v-divider :class="{ 'd-none': desktop && drawerMini }"></v-divider>
        </div>
      </div>
    </v-navigation-drawer>

    <v-app-bar app dark
      color="#212121"
      :height="$vuetify.breakpoint.smAndDown ? 56 : 64"
      :clipped-left="settings.clipped"
      class="non-selectable"
      style="z-index: 10;"
      id="topbar"
    >
      <v-app-bar-nav-icon
        @click.stop="toggleDrawer"
        :class="{ 'ml-n2': $vuetify.breakpoint.mdAndUp }"
        class="tutorial-element label-bottom tutorial-border element-icon"
        style="--label-number: '2'"
      ></v-app-bar-nav-icon>

      <a class="logo" href="/dashboard/home"><img class="non-draggable hidden-md-and-down" src="@/assets/logo.svg" /></a>

      <v-spacer></v-spacer>

      <v-btn v-if="devMode" icon @click="$store.commit('saveSetting', { name: 'locale', value: settings.locale === 'en' ? 'de' : 'en' })"><v-icon>language</v-icon></v-btn>

      <v-btn
      class="tutorial-element label-top-left element-icon" style="--label-number: '3'"
      icon
      @click="$store.commit('saveSetting', { name: 'dark', value: !settings.dark })"
      ><v-icon>invert_colors</v-icon></v-btn>

      <notifications-alerts style="margin-right: 16px;"></notifications-alerts>

      <v-menu offset-y attach>
        <template #activator="{ on }">
          <v-btn class="user-button tutorial-element label-bottom tutorial-border"
          style="height: calc(100% + 8px); --label-number: '5'; text-transform: none;"
          text v-on="on">
            <v-icon>account_circle</v-icon>
            <v-flex>
              {{ user.name }}
              <v-spacer></v-spacer>
              <v-subheader class="user-subheader">{{ user.username }}</v-subheader>
            </v-flex>
          </v-btn>
        </template>
        <v-list>
          <v-list-item to="/dashboard/account" active-class="">
            <v-icon class="user-menu-icon">perm_identity</v-icon>
            <v-list-item-title>{{ $t('user') }}</v-list-item-title>
          </v-list-item>
          <v-list-item to="/dashboard/settings" active-class="">
            <v-icon class="user-menu-icon">settings</v-icon>
            <v-list-item-title>{{ $t('settings') }}</v-list-item-title>
          </v-list-item>
          <v-list-item @click="logout">
            <v-icon class="user-menu-icon">power_settings_new</v-icon>
            <v-list-item-title>{{ $t('logout') }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>

    </v-app-bar>

    <v-content>
      <router-view />
    </v-content>

    <back-to-top-button></back-to-top-button>
    <notifications-snackbars></notifications-snackbars>
  </v-app>
</template>

<script>
import { mapState, mapMutations, mapGetters } from 'vuex'
import AccountModule from '@/components/AccountModule'
import BackToTopButton from '@/components/BackToTopButton'
import HomeModule from '@/components/HomeModule'
import NotificationsAlerts from '@/components/NotificationsAlerts'
import NotificationsSnackbars from '@/components/NotificationsSnackbars'
import SettingsModule from '@/components/SettingsModule'
import dashboardCategories from '@/config/dashboard'

export default {
  name: 'DashboardPage',
  routes () {
    return [
      { path: 'account', component: AccountModule },
      { path: 'settings', component: SettingsModule },
      { path: 'home', component: HomeModule }
    ]
  },
  components: {
    BackToTopButton,
    NotificationsAlerts,
    NotificationsSnackbars
  },
  data () {
    return {
      categories: dashboardCategories,
      drawerMini: localStorage.getItem('drawerMini') === 'true',
      drawerOpen: localStorage.getItem('drawerOpen') !== 'false'
    }
  },
  computed: {
    ...mapState(['settings']),
    ...mapGetters(['user']),
    dark () { return this.settings.dark },
    mini () { return this.settings.mini },
    desktop () { return this.$vuetify.breakpoint.lgAndUp },
    devMode () { return localStorage.getItem('dev') === 'true' }
  },
  watch: {
    dark (value) {
      this.$vuetify.theme.dark = value
    },
    mini (value) {
      if (value) {
        this.drawerMini = !this.drawerOpen
        this.drawerOpen = true
      } else {
        this.drawerOpen = !this.drawerMini
        this.drawerMini = false
      }
    },
    drawerMini (value) { localStorage.setItem('drawerMini', value) },
    drawerOpen (value) { localStorage.setItem('drawerOpen', value) }
  },
  methods: {
    ...mapMutations(['setLoginRedirect']),
    toggleDrawer () {
      if (this.settings.mini && this.desktop) this.drawerMini = !this.drawerMini
      else this.drawerOpen = !this.drawerOpen
    },
    logout () {
      this.$http.post('/api/authentication/logout').then(response => {
        this.setLoginRedirect(this.$route.fullPath)
        this.$router.push('/login')
        this.$socket.close()
      })
    }
  },
  created () {
    if (this.settings.mini && this.desktop) this.drawerOpen = true
    this.$store.dispatch('loadUser')
  }
}
</script>

<style scoped>

.dashboard-category {
  padding: 16px 0 0 32px;
}

.logo {
  height: calc(100% + 8px);
  overflow: hidden;
}

.logo > img {
  margin-top: -160px;
  margin-left: 20px;
  height: 400px;
}

.drawer {
  z-index: 11;
}

.drawer-header {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 140px;
}

.drawer-header > img {
  height: 60%;
}

.user-button {
  min-width: 160px !important;
}

.user-menu-icon {
  margin-right: 8px;
}

.user-subheader {
  height: unset;
  justify-content: center;
  font-size: 8pt;
}

</style>