view client/src/components/Sidebar.vue @ 2630:30df2d12d37f

client: sidebar: fix indicator positioning
author Markus Kottlaender <markus@intevation.de>
date Wed, 13 Mar 2019 16:45:42 +0100
parents eb69c6d27ae5
children 472b0e653644
line wrap: on
line source

<template>
  <div class="position-relative">
    <span class="indicator" v-if="!showSidebar && staging.length">
      {{ staging.length }}
    </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"></font-awesome-icon>
      </div>
      <div class="menu text-nowrap text-left">
        <router-link to="/">
          <font-awesome-icon
            class="fa-fw mr-2"
            fixed-width
            icon="map-marked-alt"
          ></font-awesome-icon>
          <span class="fix-trans-space" v-translate>Map</span>
        </router-link>
        <router-link to="/bottlenecks">
          <font-awesome-icon
            class="fa-fw mr-2"
            fixed-width
            icon="ship"
          ></font-awesome-icon>
          <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="fa-fw mr-2"
              fixed-width
              icon="clipboard-check"
            ></font-awesome-icon>
            <span class="fix-trans-space" v-translate>Staging area</span>
            <span class="indicator" v-if="showSidebar && staging.length">
              {{ staging.length }}
            </span>
          </router-link>
        </div>
        <div v-if="isSysAdmin">
          <router-link to="/stretches">
            <font-awesome-icon
              class="fa-fw mr-2"
              fixed-width
              icon="road"
            ></font-awesome-icon>
            <span class="fix-trans-space" v-translate>Define stretches</span>
          </router-link>
        </div>
        <div v-if="isWaterwayAdmin">
          <small class="text-muted pl-3"> <translate>Import</translate> </small>
          <hr class="m-0" />
          <router-link to="/importsoundingresults">
            <font-awesome-icon
              class="fa-fw mr-2"
              fixed-width
              icon="upload"
            ></font-awesome-icon>
            <span class="fix-trans-space" v-translate>Soundingresults</span>
          </router-link>
          <router-link to="/importapprovedgaugemeasurement">
            <font-awesome-icon
              class="fa-fw mr-2"
              fixed-width
              icon="upload"
            ></font-awesome-icon>
            <span class="fix-trans-space" v-translate
              >Approved Gaugemeasurements</span
            >
          </router-link>
          <router-link to="/importwaterwayprofiles">
            <font-awesome-icon
              class="fa-fw mr-2"
              fixed-width
              icon="upload"
            ></font-awesome-icon>
            <span class="fix-trans-space" v-translate>Waterway Profiles</span>
          </router-link>
          <router-link to="/importschedule">
            <font-awesome-icon
              class="fa-fw mr-2"
              fixed-width
              icon="clock"
            ></font-awesome-icon>
            <translate class="fix-trans-space">Imports</translate>
          </router-link>
          <small class="text-muted pl-3">
            <translate>Systemadministration</translate>
          </small>
          <hr class="m-0" />
        </div>
        <div v-if="isSysAdmin">
          <router-link to="/usermanagement">
            <font-awesome-icon
              class="fa-fw mr-2"
              fixed-width
              icon="users-cog"
            ></font-awesome-icon>
            <span class="fix-trans-space" v-translate>Users</span>
          </router-link>
        </div>
        <div v-if="isWaterwayAdmin">
          <router-link to="/systemconfiguration">
            <font-awesome-icon
              class="fa-fw mr-2"
              fixed-width
              icon="wrench"
            ></font-awesome-icon>
            <span class="fix-trans-space" v-translate>Configuration</span>
          </router-link>
        </div>
        <div v-if="isSysAdmin">
          <router-link to="/logs">
            <font-awesome-icon
              class="fa-fw mr-2"
              fixed-width
              icon="book"
            ></font-awesome-icon>
            <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="fa-fw mr-2"
            fixed-width
            icon="power-off"
          ></font-awesome-icon>
          <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.js";
import { displayError } from "@/lib/errors";

export default {
  name: "sidebar",
  props: ["routeName"],
  computed: {
    ...mapGetters("user", ["isSysAdmin", "isWaterwayAdmin"]),
    ...mapState("user", ["user"]),
    ...mapState("imports", ["staging"]),
    ...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.routeName == "mainview"
      );
    },
    updateIndicators() {
      this.$store.dispatch("imports/getStaging").catch(error => {
        const { status, data } = error.response;
        displayError({
          title: "Backend Error",
          message: `${status}: ${data.message || data}`
        });
      });
    }
  },
  mounted() {
    this.updateIndicators();
    setTimeout(this.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>