view client/src/components/Sidebar.vue @ 3345:954f8b751fb0

client: sidebar: moved menu item
author Markus Kottlaender <markus@intevation.de>
date Tue, 21 May 2019 10:12:17 +0200
parents 80037790032d
children d02d4e31491b
line wrap: on
line source

<template>
  <div class="position-relative">
    <span class="indicator" v-if="!showSidebar && stagingNotifications">
      {{ stagingNotifications }}
    </span>
    <div :class="sidebarStyle">
      <div
        @click="$store.commit('application/showSidebar', !showSidebar)"
        class="menubutton ui-element d-print-none p-2 bg-white rounded position-absolute d-flex justify-content-center"
      >
        <font-awesome-icon class="fa-fw" icon="bars" />
      </div>
      <div class="menu text-nowrap text-left">
        <router-link to="/">
          <font-awesome-icon class="mr-2" fixed-width icon="map-marked-alt" />
          <span class="fix-trans-space" v-translate>Map</span>
        </router-link>
        <router-link to="/bottlenecks">
          <font-awesome-icon class="mr-2" fixed-width icon="ship" />
          <span class="fix-trans-space" v-translate>Bottlenecks</span>
        </router-link>
        <div v-if="isWaterwayAdmin">
          <router-link to="/imports/overview" class="position-relative">
            <font-awesome-icon
              class="mr-2"
              fixed-width
              icon="clipboard-check"
            />
            <span class="fix-trans-space" v-translate>Import review</span>
            <span class="indicator" v-if="showSidebar && stagingNotifications">
              {{ stagingNotifications }}
            </span>
          </router-link>
          <router-link to="/imports/configuration">
            <font-awesome-icon class="mr-2" fixed-width icon="clock" />
            <translate class="fix-trans-space">Imports</translate>
          </router-link>
        </div>
        <div v-if="isSysAdmin">
          <router-link to="/stretches">
            <font-awesome-icon class="mr-2" fixed-width icon="road" />
            <span class="fix-trans-space" v-translate>Define stretches</span>
          </router-link>
        </div>
        <div v-if="isWaterwayAdmin">
          <router-link to="/sections">
            <font-awesome-icon class="mr-2" fixed-width icon="road" />
            <span class="fix-trans-space" v-translate>Define sections</span>
          </router-link>
        </div>
        <small
          class="text-muted pl-2 pb-1 d-block border-bottom"
          v-if="isSysAdmin"
        >
          <translate>Systemadministration</translate>
        </small>
        <div v-if="isSysAdmin">
          <router-link to="/usermanagement">
            <font-awesome-icon class="mr-2" fixed-width icon="users-cog" />
            <span class="fix-trans-space" v-translate>Users</span>
          </router-link>
        </div>
        <div v-if="isWaterwayAdmin">
          <router-link to="/systemconfiguration">
            <font-awesome-icon class="mr-2" fixed-width icon="wrench" />
            <span class="fix-trans-space" v-translate>Configuration</span>
          </router-link>
        </div>
        <div v-if="isSysAdmin">
          <router-link to="/logs">
            <font-awesome-icon class="mr-2" fixed-width icon="book" />
            <span class="fix-trans-space" v-translate>Logs</span>
          </router-link>
        </div>
        <hr class="m-0" />
        <a @click="logoff" href="#" class="logout">
          <font-awesome-icon class="mr-2" fixed-width icon="power-off" />
          <span class="fix-trans-space" v-translate>Logout</span> {{ user }}
        </a>
      </div>
    </div>
  </div>
</template>

<script>
/* This is Free Software under GNU Affero General Public License v >= 3.0
 * without warranty, see README.md and license for details.
 *
 * SPDX-License-Identifier: AGPL-3.0-or-later
 * License-Filename: LICENSES/AGPL-3.0.txt
 *
 * Copyright (C) 2018 by via donau
 *   – Österreichische Wasserstraßen-Gesellschaft mbH
 * Software engineering by Intevation GmbH
 *
 * Author(s):
 * Thomas Junk <thomas.junk@intevation.de>
 * Markus Kottländer <markus.kottlaender@intevation.de>
 */
import { mapGetters, mapState } from "vuex";
import { logOff } from "@/lib/session";
import { displayError } from "@/lib/errors";
import { HTTP } from "@/lib/http";

export default {
  name: "sidebar",
  data() {
    return {
      stagingNotifications: null
    };
  },
  computed: {
    ...mapGetters("user", ["isSysAdmin", "isWaterwayAdmin"]),
    ...mapState("user", ["user", "roles", "isAuthenticated"]),
    ...mapState("application", [
      "showSidebar",
      "showSearchbarLastState",
      "contextBoxContent",
      "showContextBox"
    ]),
    sidebarStyle() {
      return [
        "ui-element position-relative sidebar rounded shadow-xs d-print-none mb-auto",
        {
          sidebarcollapsed: !this.showSidebar,
          sidebarextended: this.showSidebar
        }
      ];
    }
  },
  methods: {
    logoff() {
      logOff();
    },
    toggleContextBox(context) {
      if (this.$route.path !== "/") this.$router.push("/");
      this.$store.commit("application/searchQuery", "");
      this.$store.commit("application/showContextBox", true);
      this.$store.commit("application/contextBoxContent", context);
      this.$store.commit("application/showSearchbar", true);
    },
    isActive(item) {
      return (
        this.showContextBox &&
        this.contextBoxContent === item &&
        this.$route.name == "mainview"
      );
    }
  },
  mounted() {
    const updateIndicators = () => {
      if (this.isWaterwayAdmin) {
        this.$store;
        HTTP.get("/imports?states=pending&count=true", {
          headers: { "X-Gemma-Auth": localStorage.getItem("token") }
        })
          .then(response => {
            this.stagingNotifications = response.data;
            if (this.isAuthenticated) {
              setTimeout(updateIndicators, 15000);
            }
          })
          .catch(error => {
            const { status, data } = error.response;
            displayError({
              title: "Backend Error",
              message: `${status}: ${data.message || data}`
            });
          });
      }
    };
    setTimeout(updateIndicators, 15000);
  }
};
</script>

<style lang="scss" scoped>
.menubutton {
  height: 2rem;
  width: 2rem;
  top: 0;
  left: 0;
  color: #666;
}

.indicator {
  font-size: 11px;
  line-height: 11px;
  padding: 2px 4px 1px;
  position: absolute;
  top: 18px;
  left: 0px;
  z-index: 10;
  color: #fff;
  background: #17a2b8;
  border-top-right-radius: 0.25rem;
  border-bottom-left-radius: 0.25rem;
}

.menu a {
  display: block;
  text-align: left;
  padding: 0.25rem 0.5rem;
  color: #333;
  text-decoration: none;
  font-size: 90%;
  .indicator {
    left: auto;
    right: 10px;
    top: 8px;
    border-radius: 0.25rem;
  }
  &.router-link-exact-active .indicator {
    background: #fff;
    color: #333;
  }
}

.menu a svg path {
  fill: #666;
}

.menu a:hover {
  background-color: #f8f8f8;
}

.menu a.router-link-exact-active {
  background-color: #17a2b8;
  color: #fff;
}

.menu a.router-link-exact-active svg path {
  fill: #fff;
}

.menu a.secondary.active {
  background: #ebfafd;
  color: #0f6674;
}

.menu a.secondary.active svg path {
  fill: #0f6674;
}

.sidebar {
  background-color: #ffffff;
  padding-top: $large-offset;
  opacity: $slight-transparent;
  transition: $transition-fast;
  overflow: hidden;
}

.sidebarcollapsed {
  max-height: $icon-height;
  max-width: $icon-width;
}

.sidebarextended {
  max-width: $sidebar-width;
  min-width: $sidebar-width;
}
</style>