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

add permissions

parent 2d9b8297
No related branches found
No related tags found
No related merge requests found
......@@ -29,6 +29,8 @@ function updateAxiosHeader() {
// ! À vérifier s'il y a un changement de token pendant l'éxécution de l'appli
updateAxiosHeader();
const noPermissions = { "can_view_project": true, "can_create_project": false, "can_update_project": false, "can_view_feature": true, "can_view_archived_feature": true, "can_create_feature": false, "can_update_feature": false, "can_delete_feature": false, "can_publish_feature": false, "can_create_feature_type": false, "can_view_feature_type": true, "is_project_administrator": false }
export default new Vuex.Store({
modules: {
feature_type,
......@@ -39,7 +41,7 @@ export default new Vuex.Store({
error: null,
logged: false,
user: false,
configuration:null,
configuration: null,
project_slug: null,
projects: [],
last_comments: [],
......@@ -51,7 +53,7 @@ export default new Vuex.Store({
mutations: {
error(state, data) {
return state.error = data
state.error = data;
},
SET_PROJECTS(state, projects) {
state.projects = projects;
......@@ -72,30 +74,31 @@ export default new Vuex.Store({
state.users = payload;
},
SET_COOKIE(state, cookie) {
state.cookie = cookie
state.cookie = cookie;
},
SET_STATIC_PAGES(state, staticPages) {
state.staticPages = staticPages
state.staticPages = staticPages;
},
SET_SSO(state, SSO_SETTED) {
state.SSO_SETTED = SSO_SETTED
state.SSO_SETTED = SSO_SETTED;
},
SET_USER_LEVEL_PROJECTS(state, USER_LEVEL_PROJECTS) {
state.USER_LEVEL_PROJECTS = USER_LEVEL_PROJECTS
state.USER_LEVEL_PROJECTS = USER_LEVEL_PROJECTS;
},
SET_LOGGED(state, value) {
state.logged = value
state.logged = value;
},
SET_PROJECT_COMMENTS(state, last_comments) {
state.last_comments = last_comments
state.last_comments = last_comments;
},
SET_USER_PERMISSIONS(state, userPermissions) {
state.user_permissions = userPermissions
state.user_permissions = userPermissions;
},
},
getters: {
project: state => state.projects.find((project) => project.slug === state.project_slug),
permissions: state => state.user_permissions ? state.user_permissions[state.project_slug] : noPermissions,
project_types: state => state.projects.filter(projet => projet.is_project_type),
project_user: state => state.projects.filter(projet => projet.creator === state.user.id), // todo: add id to user in api
},
......@@ -103,15 +106,15 @@ export default new Vuex.Store({
actions: {
async GET_ALL_PROJECTS({ commit }) {
function parseDate(date) {
let dateArr = date.split("/").reverse()
return new Date(dateArr[0], dateArr[1] - 1, dateArr[2])
let dateArr = date.split("/").reverse();
return new Date(dateArr[0], dateArr[1] - 1, dateArr[2]);
}
await axios
.get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}projects/`)
.then((response) => {
if (response.status === 200 && response.data) {
const orderedProjects = response.data.sort((a, b) => parseDate(b.created_on) - parseDate(a.created_on));
commit("SET_PROJECTS", orderedProjects)
commit("SET_PROJECTS", orderedProjects);
}
})
.catch((error) => {
......@@ -135,23 +138,25 @@ export default new Vuex.Store({
password: payload.password,
})
.then((response) => {
commit('error', null)
commit('error', null);
if (response && response.status === 200) {
// * use stored previous route to go back after login if page not open on login at first
let routerHistory = ''
if (router.options.routerHistory[0] != undefined){
routerHistory = router.options.routerHistory[0].name !== "login" ? router.options.routerHistory : "/"
let routerHistory = '';
if (router.options.routerHistory[0] !== undefined) {
routerHistory = router.options.routerHistory[0].name !== "login" ? router.options.routerHistory : "/";
} else {
routerHistory = "/"
routerHistory = "/";
}
commit("SET_USER", response.data.user);
router.push(routerHistory[routerHistory.length - 1] || "/")
router.push(routerHistory[routerHistory.length - 1] || "/");
dispatch("GET_USER_LEVEL_PROJECTS");
dispatch("GET_USER_LEVEL_PERMISSIONS")
}
})
.catch((error) => {
if (error.response.status === 403)
commit('error', error.response.data.detail)
if (error.response.status === 403) {
commit('error', error.response.data.detail);
}
commit("SET_USER", false);
});
}
......@@ -166,7 +171,7 @@ export default new Vuex.Store({
commit("SET_USER", user);
window.localStorage.setItem("user", JSON.stringify(user)); //? toujours nécessaire ?
}
})
})
.catch(() => {
router.push({ name: "login" });
});
......@@ -179,6 +184,7 @@ export default new Vuex.Store({
if (response && response.status === 200) {
commit("SET_USER", false); // ? better false or null
commit("SET_USER_LEVEL_PROJECTS", null);
commit("SET_USER_PERMISSIONS", null);
}
})
.catch((error) => {
......@@ -191,7 +197,7 @@ export default new Vuex.Store({
.get("./config/config.json")
.then((response) => {
if (response && response.status === 200) {
commit("SET_CONFIG", response.data)
commit("SET_CONFIG", response.data);
}
})
.catch((error) => {
......@@ -203,7 +209,7 @@ export default new Vuex.Store({
.get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}user-level-projects/`)
.then((response) => {
if (response && response.status === 200) {
commit("SET_USER_LEVEL_PROJECTS", response.data)
commit("SET_USER_LEVEL_PROJECTS", response.data);
}
})
.catch((error) => {
......@@ -216,7 +222,7 @@ export default new Vuex.Store({
.get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}user-permissions/`)
.then((response) => {
if (response && response.status === 200) {
commit("SET_USER_PERMISSIONS", response.data)
commit("SET_USER_PERMISSIONS", response.data);
}
})
.catch((error) => {
......@@ -237,7 +243,7 @@ export default new Vuex.Store({
.get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${project_slug}/comments/`)
.then((response) => {
if (response && response.status === 200) {
commit("SET_PROJECT_COMMENTS", response.data.last_comments)
commit("SET_PROJECT_COMMENTS", response.data.last_comments);
}
})
.catch((error) => {
......@@ -245,6 +251,14 @@ export default new Vuex.Store({
});
},
/* GET_PROJECT_USER({ commit }, project_slug) {
axios
.get(`${DJANGO_API_BASE}projects/${project_slug}/utilisateurs`)
.then((response) => (commit("SET_PROJECT_MEMBERS", response.data.members)))
.catch((error) => {
throw error;
});
}, */
/* GET_PROJECT_FEATURES({ commit }, project_slug) {
axios
.get(`${DJANGO_API_BASE}projects/${project_slug}/feature`)
......@@ -252,7 +266,8 @@ export default new Vuex.Store({
.catch((error) => {
throw error;
});
}, */
},
*/
/* GET_PROJECT({ commit }, project_slug) {
axios
.get(`${DJANGO_API_BASE}projects/${project_slug}/project`)
......@@ -261,14 +276,7 @@ export default new Vuex.Store({
throw error;
});
},
GET_PROJECT_USER({ commit }, project_slug) {
axios
.get(`${DJANGO_API_BASE}projects/${project_slug}/utilisateurs`)
.then((response) => (commit("SET_PROJECT_MEMBERS", response.data.members)))
.catch((error) => {
throw error;
});
}, */
*/
/* GET_COOKIE({ commit }, name) {
let cookieValue = null;
......
......@@ -7,7 +7,6 @@ axios.defaults.headers.common['X-CSRFToken'] = (name => {
return (value != null) ? unescape(value[1]) : null;
})('csrftoken');
const DJANGO_API_BASE = this.state.configuration.VUE_APP_DJANGO_API_BASE
const feature = {
namespaced: true,
......@@ -65,9 +64,9 @@ const feature = {
getters: {
},
actions: {
GET_PROJECT_FEATURES({ commit, /* dispatch */ }, project_slug) {
GET_PROJECT_FEATURES({ commit, rootState }, project_slug) {
axios
.get(`${DJANGO_API_BASE}projects/${project_slug}/feature/`)
.get(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}projects/${project_slug}/feature/`)
.then((response) => {
if (response.status === 200 && response.data) {
const features = response.data.features;
......@@ -101,7 +100,7 @@ const feature = {
if (routeName === "editer-signalement") {
axios
.put(`${DJANGO_API_BASE}features/${state.form.feature_id}/`, geojson)
.put(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/${state.form.feature_id}/`, geojson)
.then((response) => {
if (response.status === 200 && response.data) {
router.push({
......@@ -118,7 +117,7 @@ const feature = {
});
} else {
axios
.post(`${DJANGO_API_BASE}features/`, geojson)
.post(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/`, geojson)
.then((response) => {
if (response.status === 201 && response.data) {
dispatch("SEND_ATTACHMENTS", response.data.id)
......@@ -137,7 +136,7 @@ const feature = {
}
},
SEND_ATTACHMENTS({ state }, featureId) {
SEND_ATTACHMENTS({ state, rootState }, featureId) {
for (let attacht of state.attachmentFormset) {
let formdata = new FormData();
formdata.append("file", attacht.fileToImport, attacht.fileToImport.name);
......@@ -147,7 +146,7 @@ const feature = {
}
formdata.append("data", JSON.stringify(data));
axios
.post(`${DJANGO_API_BASE}features/${featureId}/attachments/`, formdata)
.post(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/${featureId}/attachments/`, formdata)
.then((response) => {
if (response.status === 200 && response.data) {
console.log(response, response.data)
......@@ -165,9 +164,9 @@ const feature = {
.getlinked_features(featureId)
.then((data) => commit("SET_FEATURE_LINKS", data));
} */
DELETE_FEATURE({ state }, feature_id) {
DELETE_FEATURE({ state, rootState }, feature_id) {
console.log("Deleting feature:", feature_id, state)
const url=`${DJANGO_API_BASE}features/${feature_id}`;
const url=`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/${feature_id}`;
axios
.delete(url, {
})
......@@ -181,7 +180,7 @@ const feature = {
//console.log("post comment", data, state)
/* axios
.post(`${DJANGO_API_BASE}feature_type/`, data)
.post(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}feature_type/`, data)
.then((response) => {
const routerHistory = router.options.routerHistory
commit("SET_USER", response.data.user);
......
......@@ -49,68 +49,70 @@
<div class="ui divided items">
<div v-for="project in projects" :key="project.slug" class="item">
<!-- {% if permissions|lookup:project.slug %} -->
<div class="ui tiny image">
<img
v-if="project.thumbnail"
class="ui small image"
:src="
project.thumbnail.includes('default')
? require('@/assets/img/default.png')
: DJANGO_BASE_URL + project.thumbnail + refreshId()
"
height="200"
/>
</div>
<div class="middle aligned content">
<router-link
:to="{
name: 'project_detail',
params: { slug: project.slug },
}"
class="header"
>{{ project.title }}</router-link
>
<div class="description">
<p>{{ project.description }}</p>
<div v-frag v-if="user_permissions[project.slug].can_view_project">
<div class="ui tiny image">
<img
v-if="project.thumbnail"
class="ui small image"
:src="
project.thumbnail.includes('default')
? require('@/assets/img/default.png')
: DJANGO_BASE_URL + project.thumbnail + refreshId()
"
height="200"
/>
</div>
<div class="meta">
<span class="right floated"
>Projet {{ project.moderation ? "" : "non" }} modéré</span
<div class="middle aligned content">
<router-link
:to="{
name: 'project_detail',
params: { slug: project.slug },
}"
class="header"
>{{ project.title }}</router-link
>
<span
>Niveau d'autorisation requis :
{{ project.access_level_pub_feature }}</span
><br />
<span>
Mon niveau d'autorisation :
<span v-if="USER_LEVEL_PROJECTS && project">{{
USER_LEVEL_PROJECTS[project.slug]
}}</span>
<span v-if="user && user.is_administrator">{{
"+ Gestionnaire métier"
}}</span>
</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 class="description">
<p>{{ project.description }}</p>
</div>
<div class="meta">
<span class="right floated"
>Projet {{ project.moderation ? "" : "non" }} modéré</span
>
<span
>Niveau d'autorisation requis :
{{ project.access_level_pub_feature }}</span
><br />
<span>
Mon niveau d'autorisation :
<span v-if="USER_LEVEL_PROJECTS && project">{{
USER_LEVEL_PROJECTS[project.slug]
}}</span>
<span v-if="user && user.is_administrator">{{
"+ Gestionnaire métier"
}}</span>
</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>
</div>
......@@ -287,7 +289,12 @@ export default {
computed: {
// todo : filter projects to user
...mapState(["user", "projects", "USER_LEVEL_PROJECTS"]),
...mapState([
"user",
"projects",
"USER_LEVEL_PROJECTS",
"user_permissions",
]),
DJANGO_BASE_URL: () => process.env.VUE_APP_DJANGO_BASE,
userFullname: function () {
if (this.user.first_name || this.user.last_name)
......
......@@ -6,8 +6,8 @@
<div class="content">
{{ feature.title || feature.feature_id }}
<div class="ui icon right floated compact buttons">
<!-- {% if permissions|lookup:'can_create_feature' %} -->
<router-link
v-if="permissions.can_create_feature"
:to="{
name: 'ajouter-signalement',
params: { slug_type_signal: $route.params.slug_type_signal },
......@@ -18,8 +18,8 @@
>
<i class="plus fitted icon"></i>
</router-link>
<!-- {% endif %} {% if permissions|lookup:'can_update_feature' %} -->
<router-link
v-if="permissions.can_update_feature"
:to="{
name: 'editer-signalement',
params: {
......@@ -31,20 +31,18 @@
>
<i class="inverted grey pencil alternate icon"></i>
</router-link>
<!-- {% endif %} {% if permissions|lookup:'can_delete_feature' %} -->
<a
v-if="permissions.can_delete_feature"
@click="isCanceling = true"
id="feature-delete"
class="ui button button-hover-red"
>
<i class="inverted grey trash alternate icon"></i>
</a>
<!-- {% endif %} -->
</div>
<div class="ui hidden divider"></div>
<div class="sub header">
{{ feature.description }}
<!-- | linebreaks -->
</div>
</div>
</h1>
......@@ -263,8 +261,7 @@
</div>
</div>
<!-- {% if permissions|lookup:'can_create_feature' %} -->
<div class="ui segment">
<div v-if="permissions.can_create_feature" class="ui segment">
<form
id="form-comment"
class="ui form"
......@@ -301,7 +298,6 @@
id="attachment_file"
@change="getAttachmentFileData($event)"
/>
<!-- {{ comment_form.attachment_file.errors }} -->
</div>
<div class="field">
<input
......@@ -363,7 +359,7 @@
<script>
import frag from "vue-frag";
import { mapState } from "vuex";
import { mapGetters, mapState } from "vuex";
import { mapUtil } from "@/assets/js/map-util.js";
import featureAPI from "@/services/feature-api";
const axios = require("axios");
......@@ -405,6 +401,7 @@ export default {
computed: {
...mapState(["user"]),
...mapGetters(["permissions"]),
...mapState("feature", ["linked_features"]),
DJANGO_BASE_URL: function () {
return this.$store.state.configuration.VUE_APP_DJANGO_BASE;
......
This diff is collapsed.
......@@ -53,9 +53,7 @@
</div>
<div class="ui bottom attached secondary segment">
<!-- // ToDo : gérer permissions -->
<!-- <div v-if="permissions.can_create_feature" class="ui styled accordion"> -->
<div class="ui styled accordion">
<div v-if="permissions.can_create_feature" class="ui styled accordion">
<div
@click="toggleShowImport"
:class="['title', { active: showImport }]"
......@@ -111,7 +109,6 @@
>
<i class="download icon"></i> Exporter
</button>
<!-- // todo gérer export -->
</div>
</div>
</div>
......@@ -174,8 +171,8 @@
<i class="right arrow icon"></i>
Voir tous les signalements
</router-link>
<!-- v-if="permissions.can_create_feature" -->
<router-link
v-if="permissions.can_create_feature"
:to="{
name: 'ajouter-signalement',
params: { slug_type_signal: structure.slug },
......@@ -184,7 +181,7 @@
>
Ajouter un signalement
</router-link>
<br /><!-- // ToDo : gérer permissions -->
<br />
</div>
</div>
</template>
......@@ -210,7 +207,7 @@ export default {
},
computed: {
...mapGetters(["project"]),
...mapGetters(["project", "permissions"]),
...mapState("feature", ["features"]),
...mapState("feature_type", ["feature_types", "importFeatureTypeData"]),
structure: function () {
......
......@@ -37,8 +37,8 @@
<div class="content">
{{ project.title }}
<div class="ui icon right floated compact buttons">
<!-- {% if permissions|lookup:'can_view_project' %} -->
<a
v-if="permissions.can_view_project"
id="subscribe-button"
class="ui button button-hover-green"
data-tooltip="S'abonner au projet"
......@@ -48,10 +48,8 @@
>
<i class="inverted grey envelope icon"></i>
</a>
<!-- {% endif %} {% if project and
permissions|lookup:'can_update_project' %} -->
<router-link
v-if="user"
v-if="permissions.can_update_project"
:to="{ name: 'project_edit', params: { slug: project.slug } }"
class="ui button button-hover-orange"
data-tooltip="Modifier le projet"
......@@ -60,12 +58,10 @@
>
<i class="inverted grey pencil alternate icon"></i>
</router-link>
<!-- {% endif %} -->
</div>
<div class="ui hidden divider"></div>
<div class="sub header">
{{ project.description }}
<!-- {{ project.description | linebreaks }} -->
</div>
</div>
</h1>
......@@ -74,7 +70,6 @@
<div class="row">
<div class="seven wide column">
<!-- // todo : Create endpoints for feature_types -->
<div class="ui middle aligned divided list">
<div
v-for="(type, index) in feature_types"
......@@ -82,7 +77,7 @@
class="item"
>
<div class="middle aligned content">
<router-link
<router-link
:to="{
name: 'details-type-signalement',
params: { feature_type_slug: type.slug },
......@@ -107,18 +102,18 @@
</router-link>
<!-- {% if project and feature_types and
permissions|lookup:'can_create_feature' %} -->
<!-- // todo: add permissions.can_create_feature and type.is_editable -->
<!-- v-if="
<!-- // ? should we get type.is_editable ? -->
<!-- v-if="
project &&
permissions.can_create_feature &&
type.is_editable
" -->
<router-link
v-if="project && permissions.can_create_feature"
:to="{
name: 'ajouter-signalement',
params: { slug_type_signal: type.slug },
}"
v-if="project && permissions.can_create_feature"
class="
ui
compact
......@@ -131,7 +126,7 @@
data-tooltip="Ajouter un signalement"
data-position="left center"
data-variation="mini"
><!-- // todo : adapt -->
>
<i class="ui plus icon"></i>
</router-link>
<router-link
......@@ -152,7 +147,7 @@
data-tooltip="Dupliquer un type de signalement"
data-position="left center"
data-variation="mini"
><!-- // todo : adapt -->
>
<i class="inverted grey copy alternate icon"></i>
</router-link>
<router-link
......@@ -183,9 +178,10 @@
<i> Le projet ne contient pas encore de type de signalements. </i>
</div>
</div>
<!-- // todo: gérer permissions: {% if project and permissions|lookup:'can_update_project' %} -->
<div class="nouveau-type-signalement">
<router-link
v-if="permissions.can_update_project"
:to="{
name: 'ajouter-type-signalement',
params: { slug: project.slug },
......@@ -329,7 +325,6 @@
</h4>
</div>
<div class="center aligned extra content">
<!-- {{ project.archive_feature|default_if_none:"0" }} jours -->
{{ project.archive_feature }} jours
</div>
</div>
......@@ -343,7 +338,6 @@
</h4>
</div>
<div class="center aligned extra content">
<!-- {{ project.delete_feature|default_if_none:"0" }} jours -->
{{ project.delete_feature }} jours
</div>
</div>
......@@ -389,7 +383,7 @@
</div>
</div>
</div>
<span v-else-if="!permissions.can_view_project">
<span v-else>
<i class="icon exclamation triangle"></i>
<span
>Vous ne disposez pas des droits nécessaires pour consulter ce
......@@ -428,7 +422,6 @@
</div>
</div>
</div>
</div>
</template>
......@@ -437,7 +430,6 @@ import frag from "vue-frag";
import { mapUtil } from "@/assets/js/map-util.js";
import { mapGetters, mapState } from "vuex";
import projectAPI from "@/services/project-api";
//import addressAPI from '@/services/address-api';
const axios = require("axios");
......@@ -469,17 +461,12 @@ export default {
slug: this.$route.params.slug,
isModalOpen: false,
is_suscriber: false,
permissions: {
// ! fake, should be replaced by api's data
can_view_project: true,
can_create_feature: true,
},
tempMessage: null,
};
},
computed: {
...mapGetters(["project"]),
...mapGetters(["project", "permissions"]),
...mapState("feature_type", ["feature_types"]),
...mapState("feature", ["features"]),
...mapState(["last_comments", "user"]),
......
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