summaryrefslogtreecommitdiffstats
path: root/webapp/src/components/DashboardPage.vue
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/src/components/DashboardPage.vue')
-rw-r--r--webapp/src/components/DashboardPage.vue237
1 files changed, 237 insertions, 0 deletions
diff --git a/webapp/src/components/DashboardPage.vue b/webapp/src/components/DashboardPage.vue
new file mode 100644
index 0000000..4004147
--- /dev/null
+++ b/webapp/src/components/DashboardPage.vue
@@ -0,0 +1,237 @@
+<i18n>
+{
+ "en": {
+ "mymodule": "My Module",
+ "yourmodule": "Your Module",
+ "backend": "External Backends",
+ "permission": "Permissions",
+ "title": "Boot Selection Server",
+ "account": "Account",
+ "settings": "Settings",
+ "logout": "Logout"
+ },
+ "de": {
+ "mymodule": "Mein Modul",
+ "yourmodule": "Dein Module",
+ "backend": "Externe Backends",
+ "permission": "Rechteverwaltung",
+ "title": "Boot Auswahl Server",
+ "account": "Konto",
+ "settings": "Einstellungen",
+ "logout": "Abmelden"
+ }
+}
+</i18n>
+
+<template>
+ <v-app :dark="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="dragging && { transform: 'translateX(' + drawerTranslateX + 'px)', transition: 'none' }"
+ persistent
+ :mini-variant="desktop && drawerMini"
+ :clipped="clipped && desktop"
+ v-model="drawerOpen"
+ fixed
+ width="250"
+ app
+ touchless
+ > <v-touch
+ @panstart="drawerDragStart"
+ @panmove="drawerDragMove"
+ @panend="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="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="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-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="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="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-app>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+import AccountModule from '@/components/AccountModule'
+import SettingsModule from '@/components/SettingsModule'
+import BackendModule from '@/components/BackendModule'
+import PermissionModule from '@/components/PermissionModule'
+import MyModule from '@/components/MyModule'
+import YourModule from '@/components/YourModule'
+
+export default {
+ name: 'DashboardPage',
+ dashboardModules: [
+ { path: 'yourmodule', component: YourModule, dashboardIcon: 'build' },
+ { path: 'mymodule', component: MyModule, dashboardIcon: 'build' },
+ { path: 'backend', component: BackendModule, dashboardIcon: 'cloud' },
+ { path: 'permission', component: PermissionModule, dashboardIcon: 'lock_open' }
+ ],
+ hiddenModules: [
+ { path: 'account', component: AccountModule },
+ { path: 'settings', component: SettingsModule }
+ ],
+ data () {
+ return {
+ dragging: false,
+ drawerTranslateX: 0,
+ drawerStartX: 0,
+ drawerMini: localStorage.getItem('drawerMini') === 'true',
+ drawerOpen: localStorage.getItem('drawerOpen') !== 'false',
+ userFullName: ''
+ }
+ },
+ computed: {
+ ...mapState(['dark', 'clipped', 'mini']),
+ desktop () { return this.$vuetify.breakpoint.lgAndUp }
+ },
+ watch: {
+ 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: {
+ toggleDrawer () {
+ if (this.mini && this.desktop) this.drawerMini = !this.drawerMini
+ else this.drawerOpen = !this.drawerOpen
+ },
+ drawerDragStart (event) {
+ this.drawerTranslateStartX = this.drawerTranslateX = this.drawerOpen ? 0 : -250
+ this.dragging = true
+ },
+ drawerDragMove (event) {
+ var newX = this.drawerTranslateStartX + event.deltaX
+ if (newX <= 0 && newX >= -250) this.drawerTranslateX = newX
+ },
+ drawerDragEnd (event) {
+ this.dragging = false
+ 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.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;
+}
+
+.drawer-icon {
+ margin-left: 16px !important;
+}
+
+</style>