Skip to content
Snippets Groups Projects
Commit 78516e5f authored by Timothee P's avatar Timothee P :sunflower:
Browse files

Get back previous page after login & add page project create an type list

parent 8368ed7e
No related branches found
No related tags found
3 merge requests!3add export-geojson & fix slug vs title in feature_list route,!2add extra_form to feature_edit,!1format date for derniers signalements, detect click outside menu dropdown and...
NODE_ENV=development
VUE_APP_LOCALE=fr-FR
DOMAIN=https://localhost:8000/api
VUE_APP_ROOT_PATH=
VUE_APP_NEXT_DEFAULT=/
# API
VUE_APP_LOGIN_API=${DOMAIN}/login
# VUE_APP_ORGANISATION_API=${DOMAIN}/organisation/
# VUE_APP_USERGROUP_API=${DOMAIN}/usergroup/
# AUTH
VUE_APP_LOGIN_API_USERNAME=admin
VUE_APP_LOGIN_API_PASSWORD=admin
VUE_APP_BASE_URL=http://localhost:8080/
VUE_APP_APPLICATION_NAME=GéoContrib
VUE_APP_APPLICATION_ABSTRACT=Application de saisie d'informations géographiques contributive
VUE_APP_LOGO_PATH=@/assets/img/logo-neogeo-circle.png
# VUE_APP_DJANGO_API_BASE=https://tim.geocontrib.dev.neogeo.fr/api/projects/
\ No newline at end of file
...@@ -67,16 +67,12 @@ ...@@ -67,16 +67,12 @@
<div class="right menu"> <div class="right menu">
<!-- // todo : create my_account page + endpoint + router --> <!-- // todo : create my_account page + endpoint + router -->
<a <router-link v-if="user" to="/my_account/" class="item">
v-if="user" {{ user.full_name || user.username }}
class="item" <!-- // ? full_name n'existe pas côté django... -->
href="{% url 'geocontrib:my_account' %}" </router-link>
> <div v-if="project && user.is_administrator" class="item ui label">
{{ user.full_name || user.username <span v-if="project"> {{ USER_LEVEL_PROJECTS }}</span
}}<!-- // ? full_name n'existe pas côté django... -->
</a>
<div v-if="project || user.is_administrator" class="item ui label">
<span v-if="project"> {{ USER_LEVEL_PROJECT }}</span
><br /> ><br />
<span v-if="user.is_administrator"> Gestionnaire métier </span> <span v-if="user.is_administrator"> Gestionnaire métier </span>
</div> </div>
...@@ -149,14 +145,17 @@ export default { ...@@ -149,14 +145,17 @@ export default {
LOGO_PATH: () => process.env.VUE_APP_LOGO_PATH, LOGO_PATH: () => process.env.VUE_APP_LOGO_PATH,
APPLICATION_NAME: () => process.env.VUE_APP_APPLICATION_NAME, APPLICATION_NAME: () => process.env.VUE_APP_APPLICATION_NAME,
PACKAGE_VERSION: () => process.env.PACKAGE_VERSION || "0", PACKAGE_VERSION: () => process.env.PACKAGE_VERSION || "0",
USER_LEVEL_PROJECT: () => this.USER_LEVEL_PROJECTS /* USER_LEVEL_PROJECT: function() {
return this.USER_LEVEL_PROJECTS.filter(item => item)
} */
}, },
created() { created() {
this.$store.dispatch("GET_COOKIE", "csrftoken"); // * ne récupère plus le cookie arès avoir vidé le cache ?! this.$store.dispatch("GET_COOKIE", "csrftoken"); // * ne récupère plus le cookie arès avoir vidé le cache ?!
}, },
methods: { methods: {
logout() { logout() {
this.$store.commit("SET_USER", false) console.log("!")
this.$store.dispatch("LOGOUT");
}, },
}, },
}; };
......
...@@ -11,23 +11,29 @@ const routes = [ ...@@ -11,23 +11,29 @@ const routes = [
component: Index component: Index
}, },
{ {
path: '/mentions/', path: '/connexion/',
name: 'Mentions', name: 'Login',
// route level code-splitting // route level code-splitting
// this generates a separate chunk (login.[hash].js) for this route // this generates a separate chunk (login.[hash].js) for this route
// which is lazy-loaded when the route is visited. // which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "login" */ '../views/flatpages/with_right_menu.vue') component: () => import(/* webpackChunkName: "login" */'../views/registration/Login.vue')
},
{
path: '/my_account/',
name: 'My_account',
component: () => import('../views/My_account.vue')
},
{
path: '/mentions/',
name: 'Mentions',
component: () => import('../views/flatpages/with_right_menu.vue')
}, },
{ {
path: '/aide/', path: '/aide/',
name: 'Aide', name: 'Aide',
component: () => import('../views/flatpages/Default.vue') component: () => import('../views/flatpages/Default.vue')
}, },
{ // * PROJECTS
path: '/connexion/',
name: 'Login',
component: () => import('../views/registration/Login.vue')
},
{ {
path: '/projet/:slug', path: '/projet/:slug',
name: 'Project_detail', name: 'Project_detail',
...@@ -40,12 +46,30 @@ const routes = [ ...@@ -40,12 +46,30 @@ const routes = [
props: true, props: true,
component: () => import('../views/project/Project_create.vue') component: () => import('../views/project/Project_create.vue')
}, },
{
path: '/Project_type_list/',
name: 'Project_type_list',
props: true,
component: () => import('../views/project/Project_type_list.vue')
},
] ]
//let routerHistory = [];
const router = new VueRouter({ const router = new VueRouter({
mode: 'history', mode: 'history',
base: process.env.BASE_URL, base: process.env.BASE_URL,
routes routes,
routerHistory: [],
scrollBehavior(to, from, savedPosition) {
const fromHistory = Boolean(savedPosition);
if (fromHistory && this.options.routerHistory.length > 0) {
this.options.routerHistory.splice(-1, 1);
} else {
this.options.routerHistory.push(from);
}
return savedPosition || { x: 0, y: 0 };
},
}) })
export default router export default router
...@@ -22,7 +22,7 @@ const SET_STATIC_PAGES = SET_STATIC_PAGES; */ ...@@ -22,7 +22,7 @@ const SET_STATIC_PAGES = SET_STATIC_PAGES; */
// })('csrftoken'); // })('csrftoken');
//} //}
const DJANGO_API_BASE = process.env.VUE_APP_DJANGO_API_BASE
export default new Vuex.Store({ export default new Vuex.Store({
// modules, // modules,
...@@ -35,7 +35,7 @@ export default new Vuex.Store({ ...@@ -35,7 +35,7 @@ export default new Vuex.Store({
projects: [], projects: [],
staticPages: null, staticPages: null,
SSO_SETTED: false, SSO_SETTED: false,
USER_LEVEL_PROJECTS: "Administrateur projet" USER_LEVEL_PROJECTS: null
}, },
mutations: { mutations: {
...@@ -75,7 +75,7 @@ export default new Vuex.Store({ ...@@ -75,7 +75,7 @@ export default new Vuex.Store({
return new Date(dateArr[0], dateArr[1] - 1, dateArr[2]) return new Date(dateArr[0], dateArr[1] - 1, dateArr[2])
} }
await axios await axios
.get("http://localhost:8000/api/projects/") .get(`${DJANGO_API_BASE}projects/`)
.then((response) => { .then((response) => {
const orderedProjects = response.data.sort((a, b) => parseDate(b.created_on) - parseDate(a.created_on)); const orderedProjects = response.data.sort((a, b) => parseDate(b.created_on) - parseDate(a.created_on));
commit("SET_PROJECTS", orderedProjects) commit("SET_PROJECTS", orderedProjects)
...@@ -86,7 +86,7 @@ export default new Vuex.Store({ ...@@ -86,7 +86,7 @@ export default new Vuex.Store({
}, },
async GET_STATIC_PAGES({ commit }) { async GET_STATIC_PAGES({ commit }) {
await axios await axios
.get("http://localhost:8000/api/aide/") .get(`${DJANGO_API_BASE}aide/`)
.then((response) => (commit("SET_STATIC_PAGES", response.data))) .then((response) => (commit("SET_STATIC_PAGES", response.data)))
.catch((error) => { .catch((error) => {
throw error; throw error;
...@@ -95,12 +95,13 @@ export default new Vuex.Store({ ...@@ -95,12 +95,13 @@ export default new Vuex.Store({
LOGIN({ commit, dispatch }, payload) { LOGIN({ commit, dispatch }, payload) {
if (payload.username && payload.password) { if (payload.username && payload.password) {
axios axios
.post("http://localhost:8000/api/login/", { .post(`${DJANGO_API_BASE}login/`, {
username: payload.username, username: payload.username,
password: payload.password, password: payload.password,
}) })
.then((response) => { .then((response) => {
commit("SET_USER", response.data.user), router.push("/"); // todo: get back to last page const routerHistory = router.options.routerHistory // * use store previous route to go back after login
commit("SET_USER", response.data.user), router.push(routerHistory[routerHistory.length - 1] || "/"); // todo: get back to original page
dispatch("GET_USER_LEVEL_PROJECTS"); dispatch("GET_USER_LEVEL_PROJECTS");
}) })
.catch((error) => { .catch((error) => {
...@@ -110,17 +111,23 @@ export default new Vuex.Store({ ...@@ -110,17 +111,23 @@ export default new Vuex.Store({
} }
}, },
LOGOUT({ commit }) {
commit("SET_USER", false) // ? better false or null
commit("SET_USER_LEVEL_PROJECTS", null)
},
GET_USER_LEVEL_PROJECTS({ commit }) { GET_USER_LEVEL_PROJECTS({ commit }) {
axios commit("SET_USER_LEVEL_PROJECTS", "Administrateur projet") // todo : use authentification)
.get(`http://localhost:8000/api/user_level_project/`) /* axios
.then((response) => (commit("SET_USER_LEVEL_PROJECTS", response))) .get(`${DJANGO_API_BASE}user_level_project/`)
.then((response) => (commit("SET_USER_LEVEL_PROJECTS", response.data)))
.catch((error) => { .catch((error) => {
throw error; throw error;
}); }); */
}, },
GET_PROJECT({ commit }, project_slug) { GET_PROJECT({ commit }, project_slug) {
axios axios
.get(`http://localhost:8000/api/projet/${project_slug}/project`) .get(`${DJANGO_API_BASE}projet/${project_slug}/project`)
.then((response) => commit("SET_PROJECT", response.data)) .then((response) => commit("SET_PROJECT", response.data))
.catch((error) => { .catch((error) => {
throw error; throw error;
...@@ -128,7 +135,7 @@ export default new Vuex.Store({ ...@@ -128,7 +135,7 @@ export default new Vuex.Store({
}, },
GET_PROJECT_USER({ commit }, project_slug) { GET_PROJECT_USER({ commit }, project_slug) {
axios axios
.get(`http://localhost:8000/api/projet/${project_slug}/utilisateurs`) .get(`${DJANGO_API_BASE}projet/${project_slug}/utilisateurs`)
.then((response) => (commit("SET_PROJECT_MEMBERS", response.data.members))) .then((response) => (commit("SET_PROJECT_MEMBERS", response.data.members)))
.catch((error) => { .catch((error) => {
throw error; throw error;
......
...@@ -20,9 +20,10 @@ ...@@ -20,9 +20,10 @@
<i class="plus icon"></i> Créer un nouveau projet <i class="plus icon"></i> Créer un nouveau projet
</router-link> </router-link>
<!-- //todo : get base url and add the rest --> <!-- //todo : get base url and add the rest -->
<a class="ui blue basic button right floated" href="#"> <router-link to="Project_type_list" class="ui blue basic button right floated">
<!-- <a class="ui blue basic button right floated" href="#"> -->
<i class="copy icon"></i> Accéder à la liste des modèles de projets <i class="copy icon"></i> Accéder à la liste des modèles de projets
</a> </router-link>
<!-- {% endif %} --> <!-- {% endif %} -->
<div v-if="projects" class="ui divided items"> <div v-if="projects" class="ui divided items">
<div v-for="project in projects" class="item" :key="project.slug"> <div v-for="project in projects" class="item" :key="project.slug">
......
<template>
<div v-frag>
<div class="fourteen wide column">
<h1>Mon compte</h1>
</div>
<div class="row">
<div class="five wide column">
<h4 class="ui horizontal divider header">PROFIL</h4>
<div class="ui divided list">
<div class="item">
<div class="right floated content">
<div class="description">
<span v-if="user.username">{{ user.username }} </span>
</div>
</div>
<div class="content">Nom d'utilisateur</div>
</div>
<div class="item">
<div class="right floated content">
<div class="description">
{% if user.get_full_name %}{{ user.get_full_name }}{% endif %}
</div>
</div>
<div class="content">Nom complet</div>
</div>
<div class="item">
<div class="right floated content">
<div class="description">
{% if user.email %}{{ user.email }}{% endif %}
</div>
</div>
<div class="content">Adresse e-mail</div>
</div>
<div class="item">
<div class="right floated content">
<div class="description">
{% if user.is_superuser %}Oui{% else %}Non{% endif %}
</div>
</div>
<div class="content">Administrateur</div>
</div>
</div>
</div>
<div class="nine wide column">
<h4 class="ui horizontal divider header">MES PROJETS</h4>
<div class="ui divided items">
{% for project in projects %} {% if permissions|lookup:project.slug %}
<div v-for="project in projects" :key="project.slug" class="item">
<div class="ui tiny image">
{% if project.thumbnail %}
<img
class="ui small image"
:src="
project.thumbnail.includes('default')
? require('@/assets/img/default.png')
: project.thumbnail
"
height="200"
/>
{% endif %}
</div>
<div class="middle aligned content">
<a class="header" href="'geocontrib:project' slug=project.slug">
{{ project.title }}
</a>
<div class="description">
<p>{{ project.description }}</p>
</div>
<div class="meta">
<span class="right floated"
>{% if project.moderation%}Projet modéré {% else %} Projet non
modéré {% endif %}</span
>
<span
>Niveau d'autorisation requis :
{{ project.access_level_pub_feature }}</span
><br />
<span>
Mon niveau d'autorisation :
{{ USER_LEVEL_PROJECTS }}
<!-- |lookup:project.slug -->
{% if user.is_administrator == True %} + Gestionnaire métier{%
endif %}
</span>
</div>
<div class="meta">
<span
class="right floated"
:data-tooltip="`Projet créé le ${project.created_on}`"
>
<i class="calendar icon"></i>&nbsp;{{ project.created_on }}
</span>
<span data-tooltip="Membres">
{{ project.nb_contributors }}&nbsp;<i class="user icon"></i>
</span>
<span data-tooltip="Signalements">
{{ project.nb_published_features }}&nbsp;<i
class="map marker icon"
></i>
</span>
<span data-tooltip="Commentaires">
{{ project.nb_published_features_comments }}&nbsp;<i
class="comment icon"
></i>
</span>
</div>
</div>
</div>
{% endif %} {% endfor %}
</div>
</div>
</div>
<div class="row">
<div class="fourteen wide column">
<div class="ui three stackable cards">
<div class="red card">
<div class="content">
<div class="center aligned header">
Mes dernières notifications reçues
</div>
<div class="center aligned description">
<div class="ui relaxed list">
<div v-for="item in events" :key="item.id" class="item">
<div class="content">
<div>
{% if item.event_type == 'create' %} {% if
item.object_type == 'feature' %}
<a :href="item.related_feature.feature_url">
Signalement créé
</a>
{% elif item.object_type == 'comment' %}
<a :href="item.related_feature.feature_url">
Commentaire créé
</a>
{% elif item.object_type == 'attachment' %}
<a :href="item.related_feature.feature_url">
Pièce jointe ajoutée
</a>
{% elif item.object_type == 'project' %}
<a :href="item.project_url"> Projet créé </a>
{% endif %} {% elif item.event_type == 'update' %} {% if
item.object_type == 'feature' %}
<a :href="item.related_feature.project_url">
Signalement mis à jour
</a>
{% elif item.object_type == 'project' %}
<a :href="item.project_url"> Projet mis à jour </a>
{% endif %} {% elif item.event_type == 'delete' %} {% if
item.object_type == 'feature' %} Signalement supprimé
({{ item.data.feature_title }}) {% endif %} {% else %}
<i>Événement inconnu</i>
{% endif %}
</div>
<div class="description">
<i
>[ {{ item.created_on }}{% if user.is_authenticated
%}, par {{ item.display_user }}{% endif %} ]</i
>
</div>
</div>
</div>
{% empty %}
<i>Aucune notification pour le moment.</i>
{% endfor %}
</div>
</div>
</div>
</div>
<div class="orange card">
<div class="content">
<div class="center aligned header">Mes derniers signalements</div>
<div class="center aligned description">
<div class="ui relaxed list">
<div v-for="item in features" :key="item.id" class="item">
<div class="content">
<div>
{% if item.related_feature %}
<a :href="item.related_feature.feature_url">{{
item.related_feature.title
}}</a>
{% else %}
{{ item.data.feature_title }} (supprimé) {% endif %}
</div>
<div class="description">
<i
>[ {{ item.created_on }}{% if user.is_authenticated
%}, par {{ item.display_user }}{% endif %} ]</i
>
</div>
</div>
</div>
{% empty %}
<i>Aucun signalement pour le moment.</i>
{% endfor %}
</div>
</div>
</div>
</div>
<div class="yellow card">
<div class="content">
<div class="center aligned header">Mes derniers commentaires</div>
<div class="center aligned description">
<div class="ui relaxed list">
<div v-for="item in comments" :key="item.id" class="item">
<div class="content">
<div>
<a :href="item.related_feature.feature_url"
>"{{ item.related_comment.comment }}"</a
>
</div>
<div class="description">
<i
>[ {{ item.created_on }}{% if user.is_authenticated
%}, par {{ item.display_user }}{% endif %} ]</i
>
</div>
</div>
</div>
{% empty %}
<i>Aucun commentaire pour le moment.</i>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import frag from "vue-frag";
import { mapState } from "vuex";
export default {
name: "My_account",
directives: {
frag,
},
data() {
return {
events: [],
features: [],
comments: [],
};
},
computed: {
// todo : filter projects to user
...mapState(["user", "projects", "USER_LEVEL_PROJECTS"]),
},
mounted() {
console.log(this.$router.history)
},
};
</script>
\ No newline at end of file
...@@ -73,9 +73,11 @@ ...@@ -73,9 +73,11 @@
<label :for="form.description.id_for_label">{{ <label :for="form.description.id_for_label">{{
form.description.label form.description.label
}}</label> }}</label>
<textarea :name="form.description.html_name" rows="5"> <textarea
{% if form.description.value %} form.description.value {% endif %}</textarea v-model="form.description.value"
> :name="form.description.html_name"
rows="5"
></textarea>
{{ form.description.errors }} {{ form.description.errors }}
</div> </div>
...@@ -134,7 +136,8 @@ ...@@ -134,7 +136,8 @@
<div <div
class="item" class="item"
:data-value=" :data-value="
x + (form.access_level_pub_feature.value === x ? selected : '') x +
(form.access_level_pub_feature.value === x ? selected : '')
" "
> >
y y
...@@ -272,7 +275,7 @@ export default { ...@@ -272,7 +275,7 @@ export default {
}, },
}, },
errors: null, errors: null,
x: null x: null,
}; };
}, },
}; };
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<div v-frag v-if="project"> <div v-frag v-if="project">
<div class="row"> <div class="row">
<div class="four wide middle aligned column"> <div class="four wide middle aligned column">
<img class="ui small spaced image" :src="project.thumbnail" /> <img class="ui small spaced image" :src="project.thumbnail.includes('default') ? require('@/assets/img/default.png') : project.thumbnail" />
<div class="ui hidden divider"></div> <div class="ui hidden divider"></div>
<div class="ui basic teal label" data-tooltip="Membres"> <div class="ui basic teal label" data-tooltip="Membres">
<i class="user icon"></i>{{ project.nb_contributors }} <i class="user icon"></i>{{ project.nb_contributors }}
......
<template>
<div class="row">
<div class="seven wide column">
<h3 class="ui header">
Créer un projet à partir d'un modèle disponible:
</h3>
<div class="ui divided items">
<div v-for="project in projects" :key="project.slug" class="item">
<div class="ui tiny image">
<img :src="project.thumbnail" />
</div>
<div class="middle aligned content">
<div class="description">
<a
:href="`project_create?create_from=${project.slug}`"
>{{ project.title }}</a
>
<p>{{ project.description }}</p>
<strong v-if="project.moderation">Projet modéré</strong>
<strong v-else>Projet non modéré</strong>
</div>
<div class="meta">
<span data-tooltip="Délai avant archivage">
{{ project.archive_feature }}&nbsp;<i class="box icon"></i>
</span>
<span data-tooltip="Délai avant suppression">
{{ project.archive_feature }}&nbsp;<i
class="trash alternate icon"
></i>
</span>
<span data-tooltip="Date de création">
{{ project.created_on }}&nbsp;<i class="calendar icon"></i>
</span>
</div>
<div class="meta">
<span data-tooltip="Visibilité des signalement publiés">
{{ project.access_level_pub_feature }}&nbsp;<i
class="eye icon"
></i>
</span>
<span data-tooltip="Visibilité des signalement archivés">
{{ project.access_level_arch_feature }}&nbsp;<i
class="archive icon"
></i>
</span>
</div>
</div>
</div>
<span v-if="!projects || projects.length === 0">Aucun projet type n'est défini.</span>
</div>
</div>
</div>
</template>
<script>
import { mapState } from "vuex"
// todo : récupérer les projets type
export default {
name: "Project_type_list",
/* data() {
return {
projects: []
}
}, */
computed: {
...mapState(["projects"])
}
}
</script>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment