Skip to content
Snippets Groups Projects
App.vue 9.13 KiB
Newer Older
<template>
  <div v-frag>
    <header class="header-menu">
Timothee P's avatar
Timothee P committed
      <div class="menu container">
        <div class="ui inverted icon menu">
          <router-link to="/" class="header item">
            <img
              class="ui mini right spaced image"
              src="@/assets/img/logo-neogeo-circle.png"
            />
            <span class="desktop">
              {{ APPLICATION_NAME }}
            </span>
            v-if="width <= 560 || (width > 560 && project)"
            :class="['ui dropdown item', { 'active visible': menuIsOpen }]"
            <!-- empty span to occupy space for style if no project -->
            <span>
              <span v-if="project"> Projet : {{ project.title }} </span>
            </span>
              :class="[
                'menu dropdown-list',
                { 'visible transition': menuIsOpen },
              ]"
                :to="{
                  name: 'project_detail',
                  params: { slug: project.slug },
                }"
                class="item"
              >
                <i class="home icon"></i>Accueil
              </router-link>
              <router-link
                :to="{
                  name: 'liste-signalements',
                  params: { slug: project.slug },
                }"
                class="item"
              >
                <i class="list icon"></i>Liste & Carte
              </router-link>

              <router-link
                v-if="
                  project &&
                  (user.is_administrator || user.is_superuser || isAdmin)
                "
                :to="{
                  name: 'project_mapping',
                  params: { slug: project.slug },
                }"
                class="item"
              >
                <i class="map icon"></i>Fonds cartographiques
              </router-link>
              <router-link
                v-if="
                  project &&
                  (user.is_administrator || user.is_superuser || isAdmin)
                "
                :to="{
                  name: 'project_members',
                  params: { slug: project.slug },
                }"
                class="item"
              >
                <i class="users icon"></i>Membres
              </router-link>

              <div class="mobile">
                <router-link v-if="user" to="/my_account/" class="item">
                  {{ userFullname || user.username || "Utilisateur inconnu" }}
                </router-link>
                <div
                  v-if="user && user.is_administrator"
                  class="item ui label vertical no-hover"
                >
                  <span v-if="USER_LEVEL_PROJECTS && project">
                    {{ USER_LEVEL_PROJECTS[project.slug] }}</span
                  >
                  <br />
                  <span v-if="user.is_administrator">
                    Gestionnaire métier
                  </span>
                </div>
                <!-- // todo : find out SSO_SETTED in django -->
                <a v-if="user && !SSO_SETTED" @click="logout" class="item"
                  ><i class="ui logout icon"></i>
                </a>
                <router-link v-else-if="!user" to="/connexion/" class="item"
                  >Se Connecter</router-link
            </div>
          </div>

          <div class="desktop flex push-right-desktop">
            <router-link v-if="user" to="/my_account/" class="item">
              {{ userFullname || user.username || "Utilisateur inconnu" }}
            </router-link>
            <div
              v-if="user || user.is_administrator"
              class="item ui label vertical no-hover"
            >
              <span v-if="USER_LEVEL_PROJECTS && project">
                {{ USER_LEVEL_PROJECTS[project.slug] }}</span
              <br />
              <span v-if="user.is_administrator"> Gestionnaire métier </span>
            <!-- // todo : find out SSO_SETTED in django -->
            <a v-if="user && !SSO_SETTED" @click="logout" class="item"
              ><i class="ui logout icon"></i>
            </a>
            <router-link v-else-if="!user" to="/connexion/" class="item"
              >Se Connecter</router-link
            >
      <div id="content" class="ui stackable grid centered container">
        <div v-if="messages && messages.length > 0" class="row">
          <div class="fourteen wide column">
            <div
              v-for="(message, index) in messages"
              :key="'message-' + index"
Timothee P's avatar
Timothee P committed
              class="ui info message"
Timothee P's avatar
Timothee P committed
              <div class="header">
                <i class="info circle icon"></i> Informations
Timothee P's avatar
Timothee P committed
              <ul class="list">
                {{
                  message.comment
                }}
              </ul>
        <div :class="{ active: loader.isLoading }" class="ui inverted dimmer">
          <div class="ui text loader">
            {{ loader.message }}
          </div>
        </div>
        <router-view />
        <!-- //* Les views sont injectées ici -->
      </div>
    </main>

    <footer>
      <div class="ui compact text menu">
        <router-link to="/mentions/" class="item">Mentions légales</router-link>
        <router-link to="/aide/" class="item">Aide</router-link>
        <p class="item">Version {{ PACKAGE_VERSION }}</p>
      </div>
    </footer>
  </div>
</template>

<script>
import frag from "vue-frag";
import { mapState } from "vuex";
import { mapGetters } from "vuex";

export default {
  name: "App",

  directives: {
    frag,
  },

  data() {
    return {
      menuIsOpen: false,
      width: window.innerWidth > 0 ? window.innerWidth : screen.width,
    ...mapState([
      "projects",
      "user",
      "SSO_SETTED",
      "USER_LEVEL_PROJECTS",
      "configuration",
Timothee P's avatar
Timothee P committed
    APPLICATION_NAME: function () {
      return this.configuration.VUE_APP_APPLICATION_NAME;
    },
    PACKAGE_VERSION: () => process.env.PACKAGE_VERSION || "0",
    userFullname: function () {
      if (this.user.first_name || this.user.last_name)
        return this.user.first_name + " " + this.user.last_name;
      return null;
    },
    isAdmin: function () {
      return this.USER_LEVEL_PROJECTS &&
        this.USER_LEVEL_PROJECTS[this.project.slug] === "Administrateur projet"
      if (e.target.closest && !e.target.closest("#menu-dropdown"))
        this.menuIsOpen = false;
  created() {
    window.addEventListener("mousedown", this.clickOutsideMenu);
  },

  beforeDestroy() {
    window.removeEventListener("mousedown", this.clickOutsideMenu);
  },
};
</script>

<style>
@import "./assets/styles/base.css";
@import "./assets/resources/semantic-ui-2.4.2/semantic.min.css";

body {
  height: 100vh;
  margin: 0;
}

header {
  min-height: 61px;
}
footer {
  min-height: 40px;
}

/* Trick */
body {
  display: flex;
  flex-direction: column;
}

/* to display loader between header and footer */
main {
  position: relative;
}

footer {
  margin-top: auto;
}

.vertical {
  flex-direction: column;
  justify-content: center;
}
.flex {
  display: flex;
}

/* keep above loader */
#menu-dropdown {
  z-index: 1001;
}

@media screen and (min-width: 560px) {
  .mobile {
    display: none !important;
  }
  .header-menu {
    min-width: 560px;
  }
  .menu.container {
    width: auto !important;
    margin-left: 1em !important;
    margin-right: 1em !important;
  }
  .push-right-desktop {
    margin-left: auto;
  }
}
@media screen and (max-width: 560px) {
  .desktop {
    display: none !important;
  }
    left: -70px !important; /* should be the same than belows */
  .menu.container a.header {
    width: 70px;
  }
  .menu.container a.header > img {
    margin: 0;
  }
  #menu-dropdown {
    width: calc(100vw - 70px);
    justify-content: space-between;
  }
  #menu-dropdown > span {
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
  }
}

.ui.menu .ui.dropdown .menu > .item.no-hover:hover {
  cursor: auto !important;
  background: white !important;
}
/* copy style to apply inside nested div */
.ui.menu .ui.dropdown .menu .item {
  margin: 0;
  text-align: left;
  font-size: 1em !important;
  padding: 0.78571429em 1.14285714em !important;
  background: 0 0 !important;
  color: #252525 !important;
  text-transform: none !important;
  font-weight: 400 !important;
  box-shadow: none !important;
  transition: none !important;
}