<template> <div v-frag> <header class="header-menu"> <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> </router-link> <div v-if="width <= 560 || (width > 560 && project)" id="menu-dropdown" :class="['ui dropdown item', { 'active visible': menuIsOpen }]" @click="menuIsOpen = !menuIsOpen" > <!-- empty span to occupy space for style if no project --> <span> <span v-if="project"> Projet : {{ project.title }} </span> </span> <i class="dropdown icon"></i> <div :class="[ 'menu dropdown-list', { 'visible transition': menuIsOpen }, ]" style="z-index: 401" > <router-link v-if="project" :to="{ name: 'project_detail', params: { slug: project.slug }, }" class="item" > <i class="home icon"></i>Accueil </router-link> <router-link v-if="project" :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> <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> </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> </header> <main> <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" class="ui info message" > <div class="header"> <i class="info circle icon"></i> Informations </div> <ul class="list"> {{ message.comment }} </ul> </div> </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, rightMenuIsOpen: true, width: window.innerWidth > 0 ? window.innerWidth : screen.width, }; }, computed: { ...mapState([ "projects", "user", "SSO_SETTED", "USER_LEVEL_PROJECTS", "configuration", "messages", ]), ...mapGetters(["project"]), 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" ? true : false; }, }, methods: { logout() { this.$store.dispatch("LOGOUT"); }, clickOutsideMenu(e) { 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; } footer { margin-top: auto; } .vertical { flex-direction: column; justify-content: center; } @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; } } .flex { display: flex; } @media screen and (max-width: 560px) { .desktop { display: none !important; } div.dropdown-list { width: 100vw; 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; } </style>