Something went wrong on our end
-
Timothee P authoredTimothee P authored
Project_members.vue 9.32 KiB
<template>
<div class="fourteen wide column">
<h1 class="ui header">
Gérer les membres
</h1>
<h4>Ajouter un membre</h4>
<div
id="form-feature-edit"
class="ui form"
name="add-member"
>
<div class="two fields">
<div class="field">
<Dropdown
:options="userOptions"
:selected="newMember.user.name"
:selection.sync="newMember.user"
:search="true"
:clearable="true"
/>
<ul
id="errorlist"
class="errorlist"
>
<li
v-for="error in newMember.errors"
:key="error"
>
{{ error }}
</li>
</ul>
</div>
<div class="field">
<Dropdown
:options="levelOptions"
:selected="newMember.role.name"
:selection.sync="newMember.role"
/>
</div>
</div>
<button
type="button"
class="ui green icon button"
:disabled="newMember.user"
@click="addMember"
>
<i class="white add icon" />
<span class="padding-1">Ajouter</span>
</button>
</div>
<h4>Modifier le rôle d'un membre</h4>
<div
id="form-members"
class="ui form"
>
<table class="ui red table">
<thead>
<tr>
<th>
Membre
<i
:class="{
down: isSortedAsc('member'),
up: isSortedDesc('member'),
}"
class="icon sort"
@click="changeSort('member')"
/>
</th>
<th>
Niveau d'autorisation
<i
:class="{
down: isSortedAsc('role'),
up: isSortedDesc('role'),
}"
class="icon sort"
@click="changeSort('role')"
/>
</th>
</tr>
</thead>
<tbody>
<tr
v-for="member in projectMembers"
:key="member.username"
>
<td>
{{ member.user.last_name }} {{ member.user.first_name }}<br><i>{{ member.user.username }}</i>
</td>
<td>
<div class="required field online">
<Dropdown
:options="levelOptions"
:selected="member.userLevel.name"
:selection.sync="member.userLevel"
:search="true"
/>
<button
type="button"
class="ui icon button"
@click="removeMember(member)"
>
<i class="times icon" />
</button>
</div>
</td>
</tr>
</tbody>
</table>
<div class="ui divider" />
<button
type="button"
class="ui teal icon button"
@click="saveMembers"
>
<i class="white save icon" /> Enregistrer les changements
</button>
</div>
</div>
</template>
<script>
import axios from '@/axios-client.js';
import frag from 'vue-frag';
import { mapState } from 'vuex';
import Dropdown from '@/components/Dropdown.vue';
export default {
name: 'ProjectMembers',
directives: {
frag,
},
components: {
Dropdown,
},
data() {
return {
projectUsers: [],
options: [
{ name: 'Utilisateur connecté', value: 'logged_user' },
{ name: 'Contributeur', value: 'contributor' },
{ name: 'Super Contributeur', value: 'super_contributor' },
{ name: 'Modérateur', value: 'moderator' },
{ name: 'Administrateur projet', value: 'admin' },
],
newMember: {
errors: [],
user: {
name: '',
value: '',
},
role: {
name: 'Contributeur',
value: 'contributor',
},
},
sort: {
column: '',
ascending: true,
},
};
},
computed: {
...mapState('projects', ['project']),
userOptions: function () {
return this.projectUsers
.filter((el) => el.userLevel.value === 'logged_user')
.map((el) => {
let name = el.user.first_name || '';
if (el.user.last_name) {
name = name + ' ' + el.user.last_name;
}
return {
name: [name, el.user.username],
value: el.user.id,
};
});
},
levelOptions: function () {
return this.options.filter(
(el) =>
(this.project && this.project.moderation ? el : el.value !== 'moderator') &&
el.value !== 'logged_user'
);
},
projectMembers() {
return this.projectUsers
.filter((el) => el.userLevel.value !== 'logged_user')
.sort((a, b) => {
if (this.sort.column !== '') {
if (this.sort.column === 'member') {
const textA = a.user.username.toUpperCase();
const textB = b.user.username.toUpperCase();
if (this.sort.ascending) {
return textA < textB ? -1 : textA > textB ? 1 : 0;
} else {
return textA > textB ? -1 : textA < textB ? 1 : 0;
}
} else if (this.sort.column === 'role') {
const textA = a.userLevel.name.toUpperCase();
const textB = b.userLevel.name.toUpperCase();
if (this.sort.ascending) {
return textA < textB ? -1 : textA > textB ? 1 : 0;
} else {
return textA > textB ? -1 : textA < textB ? 1 : 0;
}
}
} else {
return 0;
}
});
},
},
created() {
if (!this.project) {
this.$store.dispatch('projects/GET_PROJECT', this.$route.params.slug);
this.$store.dispatch('projects/GET_PROJECT_INFO', this.$route.params.slug);
}
this.populateMembers();
},
destroyed() {
//* allow user to change page if ever stuck on loader
this.$store.commit('DISCARD_LOADER');
},
methods: {
validateNewMember() {
this.newMember.errors = [];
if (!this.newMember.user.value) {
this.newMember.errors.push('Veuillez compléter ce champ.');
return false;
}
return true;
},
changeUserRole(id, role) {
const indexOfUser = this.projectUsers.findIndex(
(el) => el.user.id === id
);
//* modify its userLever
this.projectUsers[indexOfUser].userLevel = role;
},
addMember() {
if (this.validateNewMember()) {
this.changeUserRole(this.newMember.user.value, this.newMember.role);
//* empty add form
this.newMember.user = { value: '', name: '' };
}
},
isSortedAsc(column) {
return this.sort.column === column && this.sort.ascending;
},
isSortedDesc(column) {
return this.sort.column === column && !this.sort.ascending;
},
changeSort(column) {
if (this.sort.column === column) {
//changer order
this.sort.ascending = !this.sort.ascending;
} else {
this.sort.column = column;
this.sort.ascending = true;
}
},
removeMember(member) {
this.changeUserRole(member.user.id, {
name: 'Utilisateur connecté',
value: 'logged_user',
});
},
saveMembers() {
const data = this.projectUsers.map((member) => {
return {
user: member.user,
level: {
display: member.userLevel.name,
codename: member.userLevel.value,
},
};
});
axios
.put(
`${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.project.slug}/utilisateurs/`,
data
)
.then((response) => {
if (response.status === 200) {
this.$store.dispatch('GET_USER_LEVEL_PROJECTS'); //* update user status in top right menu
this.$store.commit('DISPLAY_MESSAGE', { comment: 'Permissions mises à jour', level: 'positive' });
} else {
this.$store.commit(
'DISPLAY_MESSAGE',
{
comment : "Une erreur s'est produite pendant la mises à jour des permissions",
level: 'negative'
}
);
}
})
.catch((error) => {
throw error;
});
},
fetchMembers() {
// todo: move function to a service
return axios
.get(
`${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/utilisateurs/`
)
.then((response) => response.data)
.catch((error) => {
throw error;
});
},
populateMembers() {
this.$store.commit(
'DISPLAY_LOADER',
'Récupération des membres en cours...'
);
this.fetchMembers().then((members) => {
this.$store.commit('DISCARD_LOADER');
this.projectUsers = members.map((el) => {
return {
userLevel: { name: el.level.display, value: el.level.codename },
...el,
};
});
});
},
},
};
</script>
<style>
.padding-1 {
padding: 0 1em;
}
i.icon.sort:not(.down):not(.up) {
color: rgb(220, 220, 220);
}
.online {
display: flex;
}
</style>