Something went wrong on our end
Forked from
GéoContrib / Géocontrib Frontend
1331 commits behind the upstream repository.
-
Timothee P authoredTimothee P authored
App.vue 12.48 KiB
<template>
<div v-frag>
<script
type="application/javascript"
:src="
baseUrl +
'resources/leaflet-control-geocoder-1.13.0/Control.Geocoder.js'
"
/>
<header class="header-menu">
<div class="menu container">
<div class="ui inverted icon menu">
<router-link
:is="isSharedProject ? 'span' : 'router-link'"
:to="isSharedProject ? '' : '/'"
:class="['header item', {disable: isSharedProject}]"
>
<img
class="ui mini right spaced image"
:src="logo"
>
<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" />
<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" />Accueil
</router-link>
<router-link
v-if="project"
:to="{
name: 'liste-signalements',
params: { slug: project.slug },
}"
class="item"
>
<i class="list icon" />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" />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" />Membres
</router-link>
<div class="mobile">
<router-link
v-if="user"
:to="{
name: 'my_account',
params: { slug: isSharedProject && $route.params.slug ? $route.params.slug : null }
}"
class="item"
>
{{ userFullname || user.username || "Utilisateur inconnu" }}
</router-link>
<div
v-if="USER_LEVEL_PROJECTS && project"
class="item ui label vertical no-hover"
>
{{ USER_LEVEL_PROJECTS[project.slug] }}
<br>
</div>
<div
v-if="user && user.is_administrator"
class="item ui label vertical no-hover"
>
Gestionnaire métier
</div>
<div
v-if="!DISABLE_LOGIN_BUTTON"
v-frag
>
<a
v-if="user"
class="item"
@click="logout"
><i class="ui logout icon" />
</a>
<router-link
v-else-if="!user && !SSO_LOGIN_URL"
:to="{ name : 'login' }"
class="item"
>
Se connecter
</router-link>
<a
v-else
class="item"
:href="SSO_LOGIN_URL"
>Se connecter</a>
</div>
</div>
</div>
</div>
<div class="desktop flex push-right-desktop item title">
<span>
{{ APPLICATION_ABSTRACT }}
</span>
</div>
<div class="desktop flex push-right-desktop">
<router-link
v-if="user"
:to="{
name: 'my_account',
params: { slug: isSharedProject && $route.params.slug ? $route.params.slug : null }
}"
class="item"
>
{{ userFullname || user.username || "Utilisateur inconnu" }}
</router-link>
<div
v-if="USER_LEVEL_PROJECTS && project"
class="item ui label vertical no-hover"
>
{{ USER_LEVEL_PROJECTS[project.slug] }}
<br>
</div>
<div
v-if="user && user.is_administrator"
class="item ui label vertical no-hover"
>
Gestionnaire métier
</div>
<div
v-if="!DISABLE_LOGIN_BUTTON"
v-frag
>
<a
v-if="user"
class="item"
@click="logout"
><i class="ui logout icon" />
</a>
<router-link
v-else-if="!user && !SSO_LOGIN_URL"
:to="{ name : 'login' }"
class="item"
>
Se Connecter
</router-link>
<a
v-else
class="item"
:href="SSO_LOGIN_URL"
>Se connecter</a>
</div>
</div>
</div>
</div>
</header>
<main>
<div
id="content"
class="ui stackable grid centered container"
>
<transition name="fadeDownUp">
<div
v-if="messages && messages.length > 0"
class="row over-content"
>
<div class="fourteen wide column">
<div
v-for="(message, index) in messages"
:key="'message-' + index"
:class="['ui', message.level ? message.level : 'info', 'message']"
>
<i
class="close icon"
@click="DISCARD_MESSAGE(message)"
/>
<div class="header">
<i class="info circle icon" />
Informations
</div>
<ul class="list">
{{
message.comment
}}
</ul>
</div>
</div>
</div>
</transition>
<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="{name: 'mentions'}"
class="item"
>
Mentions légales
</router-link>
<router-link
:to="{name: 'aide'}"
class="item"
>
Aide
</router-link>
<p class="item">
Version {{ PACKAGE_VERSION }}
</p>
</div>
</footer>
</div>
</template>
<script>
import frag from 'vue-frag';
import { mapMutations, mapState } from 'vuex';
export default {
name: 'App',
directives: {
frag,
},
data() {
return {
menuIsOpen: false,
rightMenuIsOpen: true,
baseUrl: this.$store.state.configuration.BASE_URL,
width: window.innerWidth > 0 ? window.innerWidth : screen.width,
};
},
computed: {
...mapState([
'user',
'USER_LEVEL_PROJECTS',
'configuration',
'messages',
'loader',
]),
...mapState('projects', [
'projects',
'project',
]),
APPLICATION_NAME() {
return this.configuration.VUE_APP_APPLICATION_NAME;
},
APPLICATION_ABSTRACT() {
return this.$store.state.configuration.VUE_APP_APPLICATION_ABSTRACT;
},
DISABLE_LOGIN_BUTTON() {
return this.configuration.VUE_APP_DISABLE_LOGIN_BUTTON;
},
SSO_LOGIN_URL() {
return this.configuration.VUE_APP_LOGIN_URL;
},
PACKAGE_VERSION: () => process.env.PACKAGE_VERSION || '0',
logo() {
return this.configuration.VUE_APP_LOGO_PATH;
},
userFullname() {
if (this.user.first_name || this.user.last_name)
return this.user.first_name + ' ' + this.user.last_name;
return null;
},
isAdmin() {
return this.USER_LEVEL_PROJECTS &&
this.USER_LEVEL_PROJECTS[this.project.slug] === 'Administrateur projet'
? true
: false;
},
isSharedProject() {
return this.$route.path.includes('projet-partage');
}
},
created() {
window.addEventListener('mousedown', this.clickOutsideMenu);
},
beforeDestroy() {
window.removeEventListener('mousedown', this.clickOutsideMenu);
},
methods: {
...mapMutations(['DISCARD_MESSAGE']),
logout() {
this.$store.dispatch('LOGOUT');
},
clickOutsideMenu(e) {
if (e.target.closest && !e.target.closest('#menu-dropdown'))
this.menuIsOpen = false;
},
},
};
</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;
}
.leaflet-container {
background: white !important;
}
.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;
}
.push-right-desktop {
margin-left: auto;
}
}
@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;
}
.item.title::before {
background: none !important;
}
.ui.grid > .row.over-content {
position: absolute;
z-index: 99;
opacity: 0.95;
}
.fadeDownUp-enter-active {
animation: fadeInDown .5s;
}
.fadeDownUp-leave-active {
animation: fadeOutUp .5s;
}
@keyframes fadeOutUp {
0% {
opacity: 1;
}
100% {
opacity: 0;
transform: translate3d(0, -100%, 0);
}
}
@keyframes fadeInDown {
from {
opacity: 0;
transform: translate3d(0, -100%, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
.ui.message > .close.icon {
cursor: pointer;
position: absolute;
margin: 0em;
top: 0.78575em;
right: 0.5em;
opacity: 0.7;
-webkit-transition: opacity 0.1s ease;
transition: opacity 0.1s ease;
}
</style>
<style scoped>
.disable:hover {
cursor: default !important;
background-color: #373636 !important;
}
</style>