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


         
                                







                                     
                                  










                                     
                                                      









                                                              
                                  

                                           
                                            




                          




















                                                                                                                            

                          
                                                                        


                                                                                                

                                                                                                                                                                           





                                                                  
                                                                 


                                                                        
                                                                  














                                                                         
















                                     



           

                                                         

                                                            

                                                        



                        
                                                                         








                                                                                   


                              
                      
                       
                          





                                                                 

                                           
                                    




                                                           
                                                                                     


                                                                            
      
                                                                

          





















                                             












                                                                     
                                        
                     
                                                                                


                                             
                                                                                                                   
                                                                                          


                            
                                               

                                                              
              

                                                                   
       


                           
                                               





                                                                                                                     







                                                       
                                                                  

























































                                                   
        
<i18n>
{
  "en": {
    "group": "Groups / Clients",
    "backend": "External Backends",
    "permission": "Permissions",
    "title": "Boot Selection Server",
    "account": "Account",
    "settings": "Settings",
    "logout": "Logout"
  },
  "de": {
    "group": "Gruppen / Clienten",
    "backend": "Externe Backends",
    "permission": "Rechteverwaltung",
    "title": "Boot Auswahl Server",
    "account": "Konto",
    "settings": "Einstellungen",
    "logout": "Abmelden"
  }
}
</i18n>

<template>
  <v-app :dark="settings.dark" class="non-selectable">
    <v-touch
      @panstart="drawerDragStart"
      @panmove="drawerDragMove"
      @panend="drawerDragEnd"
      @pancancel="drawerDragEnd"
      :pan-options="{ direction: 'horizontal', threshold: 0 }"
      class="drawer-handle-closed"
    ></v-touch>
    <v-navigation-drawer
      class="drawer"
      :style="drawerDraggingStyle"
      persistent
      :mini-variant="desktop && drawerMini"
      :clipped="settings.clipped && desktop"
      v-model="drawerOpen"
      fixed
      width="250"
      app
      touchless
    >
      <v-touch
        @panstart="drawerDragStart"
        @panmove="drawerDragMove"
        @panend="drawerDragEnd"
        @pancancel="drawerDragEnd"
        :pan-options="{ direction: 'horizontal', threshold: 0 }"
        class="drawer-handle-open"
      >
        <div class="drawer-header grey darken-4 hidden-lg-and-up"><img class="logo" src="@/assets/logo.svg" /></div>
        <v-list>
          <v-list-tile ripple v-for="child in $options.dashboardModules" :key="child.path" :to="'/dashboard/' + child.path">
            <v-list-tile-action>
              <v-icon v-html="child.dashboardIcon"></v-icon>
            </v-list-tile-action>
            <v-list-tile-content>
              <v-list-tile-title v-text="$t(child.path)"></v-list-tile-title>
            </v-list-tile-content>
          </v-list-tile>
        </v-list>
      </v-touch>
    </v-navigation-drawer>

    <v-toolbar dark class="topbar" app :clipped-left="settings.clipped">
      <v-toolbar-side-icon class="drawer-icon" @click.stop="toggleDrawer"></v-toolbar-side-icon>
      <img class="logo non-draggable hidden-md-and-down" src="@/assets/logo.svg" />
      <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 v-if="devMode" icon @click="$store.commit('saveSetting', { name: 'dark', value: !settings.dark })"><v-icon>invert_colors</v-icon></v-btn>
      <v-toolbar-items>
        <v-menu offset-y>
          <v-btn class="user-button" flat slot="activator">
            <v-icon left>account_circle</v-icon>{{ userFullName }}
          </v-btn>
          <v-list>
            <v-list-tile to="/dashboard/account" active-class="">
              <v-icon class="user-menu-icon">perm_identity</v-icon>
              <v-list-tile-title>{{ $t('account') }}</v-list-tile-title>
            </v-list-tile>
            <v-list-tile to="/dashboard/settings" active-class="">
              <v-icon class="user-menu-icon">settings</v-icon>
              <v-list-tile-title>{{ $t('settings') }}</v-list-tile-title>
            </v-list-tile>
            <v-list-tile @click="logout">
              <v-icon class="user-menu-icon">power_settings_new</v-icon>
              <v-list-tile-title>{{ $t('logout') }}</v-list-tile-title>
            </v-list-tile>
          </v-list>
        </v-menu>
      </v-toolbar-items>
    </v-toolbar>

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

    <v-snackbar
      color="primary"
      v-model="showSnackbar"
      bottom
      right
      :timeout="2000"
    >
      {{ snackbarText }}
      <v-btn
        flat
        @click="showSnackbar = false"
      >
        Close
      </v-btn>
    </v-snackbar>

  </v-app>
</template>

<script>
import { mapState, mapGetters, mapMutations } from 'vuex'
import GroupModule from '@/components/GroupModule'
import BackendModule from '@/components/BackendModule'
import PermissionModule from '@/components/PermissionModule'
import AccountModule from '@/components/AccountModule'
import SettingsModule from '@/components/SettingsModule'

export default {
  name: 'DashboardPage',
  dashboardModules: [
    { path: 'group', component: GroupModule, dashboardIcon: 'category' },
    { path: 'backend', component: BackendModule, dashboardIcon: 'cloud' },
    { path: 'permission', component: PermissionModule, dashboardIcon: 'lock_open' }
  ],
  hiddenModules: [
    { path: 'account', component: AccountModule },
    { path: 'settings', component: SettingsModule }
  ],
  data () {
    return {
      snackbarsInQueue: false,
      showSnackbar: false,
      snackbarText: 'MESSAGE',
      dragging: false,
      drawerWidth: 250,
      drawerTranslateX: 0,
      drawerMini: localStorage.getItem('drawerMini') === 'true',
      drawerOpen: localStorage.getItem('drawerOpen') !== 'false',
      userFullName: ''
    }
  },
  computed: {
    ...mapState(['settings', 'snackbars']),
    mini () { return this.settings.mini },
    ...mapGetters(['nextSnackbar']),
    desktop () { return this.$vuetify.breakpoint.lgAndUp },
    drawerDraggingStyle () {
      var style = {}
      if (this.dragging) {
        style.transition = 'none'
        if (this.settings.mini && this.desktop) style.width = this.drawerWidth + 'px'
        else style.transform = 'translateX(' + this.drawerTranslateX + 'px)'
      }
      return style
    },
    devMode () { return localStorage.getItem('dev') === 'true' }
  },
  watch: {
    showSnackbar (value) {
      if (!value) {
        var text = this.nextSnackbar
        if (text) {
          this.shiftSnackbars()
          setTimeout(() => {
            this.snackbarText = text
            this.showSnackbar = true
          }, 500)
        } else {
          this.snackbarsInQueue = false
        }
      }
    },
    snackbars (value) {
      if (!this.snackbarsInQueue) {
        this.snackbarsInQueue = true
        this.snackbarText = this.nextSnackbar
        this.shiftSnackbars()
        this.showSnackbar = true
      }
    },
    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(['shiftSnackbars']),
    toggleDrawer () {
      if (this.settings.mini && this.desktop) this.drawerMini = !this.drawerMini
      else this.drawerOpen = !this.drawerOpen
    },
    drawerDragStart (event) {
      if (this.settings.mini && this.desktop) this.drawerWidth = this.drawerStartWidth = this.drawerMini ? 80 : 250
      else this.drawerTranslateStartX = this.drawerTranslateX = this.drawerOpen ? 0 : -250
      this.dragging = true
    },
    drawerDragMove (event) {
      if (this.settings.mini && this.desktop) {
        let newX = this.drawerStartWidth + event.deltaX
        if (newX >= 80 && newX <= 250) this.drawerWidth = newX
      } else {
        let newX = this.drawerTranslateStartX + event.deltaX
        if (newX <= 0 && newX >= -250) this.drawerTranslateX = newX
      }
    },
    drawerDragEnd (event) {
      this.dragging = false
      if (this.settings.mini && this.desktop) {
        if ((this.drawerWidth < 100 && event.velocityX <= 0) || event.velocityX < -0.4) this.drawerMini = true
        else this.drawerMini = false
      } else {
        if ((this.drawerTranslateX < -100 && event.velocityX <= 0) || event.velocityX < -0.4) this.drawerOpen = false
        else this.drawerOpen = true
      }
    },
    logout () {
      this.$http.post('/api/logout').then(response => {
        this.$router.push('/login')
      })
    }
  },
  created () {
    if (this.settings.mini && this.desktop) this.drawerOpen = true
    this.$http('/api/user/info').then(response => {
      this.userFullName = response.data.name
    })
  }
}
</script>

<style scoped>

.topbar {
  overflow: hidden;
}

.logo {
  margin-left: 20px;
  height: 400px;
}

.drawer {
  height: 100vh !important;
}

.drawer-handle-closed {
  position: fixed;
  height: 100vh;
  top: 0;
  left: 0;
  width: 15px;
  z-index: 1000;
  /* border: 2px red solid; */
}

.drawer-handle-open {
  position: absolute;
  height: 100%;
  width: 100%;
  /* border: 2px red solid; */
}

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

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

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

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

</style>