Add a proper setting menu

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2020-03-12 14:29:21 +01:00
parent fb6add8563
commit 299b686612
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
26 changed files with 613 additions and 405 deletions

View File

@ -52,7 +52,7 @@
<!-- {{ $t('Create group') }}-->
<!-- </b-navbar-item>-->
<b-navbar-item v-if="currentUser.role === ICurrentUserRole.ADMINISTRATOR" tag="router-link" :to="{ name: RouteName.DASHBOARD }">
<b-navbar-item v-if="currentUser.role === ICurrentUserRole.ADMINISTRATOR" tag="router-link" :to="{ name: RouteName.ADMIN_DASHBOARD }">
{{ $t('Administration') }}
</b-navbar-item>

View File

@ -0,0 +1,54 @@
<template>
<li class="setting-menu-item" :class="{ active: isActive }">
<router-link v-if="menuItem.to" :to="menuItem.to">
<span>{{ menuItem.title }}</span>
</router-link>
<span v-else>{{ menuItem.title }}</span>
</li>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import { ISettingMenuSection } from '@/types/setting-menu.model';
@Component
export default class SettingMenuItem extends Vue {
@Prop({ required: true, type: Object }) menuItem!: ISettingMenuSection;
get isActive() {
if (!this.menuItem.to) return false;
if (this.menuItem.to.name === this.$route.name) {
if (this.menuItem.to.params) {
return this.menuItem.to.params.identityName === this.$route.params.identityName;
}
return true;
}
return false;
}
}
</script>
<style lang="scss" scoped>
@import "@/variables.scss";
li.setting-menu-item {
font-size: 1.05rem;
background-color: #fff1de;
color: $primary;
margin: auto;
span {
padding: 5px 15px;
display: block;
}
a {
display: block;
color: inherit;
}
&:hover, &.active {
cursor: pointer;
background-color: lighten(#fea72b, 10%);
}
}
</style>

View File

@ -0,0 +1,48 @@
<template>
<li :class="{ active: sectionActive }">
<router-link v-if="menuSection.to" :to="menuSection.to">{{ menuSection.title }}</router-link>
<b v-else>{{ menuSection.title }}</b>
<ul>
<setting-menu-item :menu-item="item" v-for="item in menuSection.items" :key="item.title" />
</ul>
</li>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import { ISettingMenuSection } from '@/types/setting-menu.model';
import SettingMenuItem from '@/components/Settings/SettingMenuItem.vue';
@Component({
components: { SettingMenuItem },
})
export default class SettingMenuSection extends Vue {
@Prop({ required: true, type: Object }) menuSection!: ISettingMenuSection;
get sectionActive(): boolean|undefined {
return this.menuSection.items && this.menuSection.items.some((({ to }) => to && to.name === this.$route.name));
}
}
</script>
<style lang="scss" scoped>
@import "@/variables.scss";
li {
font-size: 1.3rem;
background-color: $secondary;
color: $primary;
margin: 2px auto;
&.active {
background-color: #fea72b;
}
a, b {
cursor: pointer;
margin: 5px 0;
display: block;
padding: 5px 10px;
color: inherit;
font-weight: 500;
}
}
</style>

View File

@ -0,0 +1,18 @@
<template>
<ul>
<SettingMenuSection v-for="section in menuValue" :key="section.title" :menu-section="section" />
</ul>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import SettingMenuSection from '@/components/Settings/SettingMenuSection.vue';
import { ISettingMenuSection } from '@/types/setting-menu.model';
@Component({
components: { SettingMenuSection },
})
export default class SettingsMenu extends Vue {
@Prop({ required: true, type: Array }) menu!: ISettingMenuSection[];
get menuValue() { return this.menu; }
}
</script>

View File

@ -8,7 +8,7 @@
"About this instance": "About this instance",
"About": "About",
"Accepted": "Accepted",
"Account settings": "Account settings",
"Account": "Account",
"Add a note": "Add a note",
"Add an address": "Add an address",
"Add an instance": "Add an instance",
@ -17,12 +17,13 @@
"Add": "Add",
"Additional comments": "Additional comments",
"Admin settings successfully saved.": "Admin settings successfully saved.",
"Admin settings": "Admin settings",
"Admin": "Admin",
"Administration": "Administration",
"All the places have already been taken": "All the places have been taken|One place is still available|{places} places are still available",
"Allow all comments": "Allow all comments",
"Allow registrations": "Allow registrations",
"An error has occurred.": "An error has occurred.",
"Anonymous participant": "Anonymous participant",
"Anonymous participants will be asked to confirm their participation through e-mail.": "Anonymous participants will be asked to confirm their participation through e-mail.",
"Anonymous participations": "Anonymous participations",
"Approve": "Approve",
@ -59,6 +60,7 @@
"Comment from @{username} reported": "Comment from @{username} reported",
"Comments have been closed.": "Comments have been closed.",
"Comments": "Comments",
"Confirm my participation": "Confirm my participation",
"Confirm my particpation": "Confirm my particpation",
"Confirmed: Will happen": "Confirmed: Will happen",
"Continue editing": "Continue editing",
@ -76,6 +78,7 @@
"Create": "Create",
"Creator": "Creator",
"Current identity has been changed to {identityName} in order to manage this event.": "Current identity has been changed to {identityName} in order to manage this event.",
"Current page": "Current page",
"Custom URL": "Custom URL",
"Custom text": "Custom text",
"Custom": "Custom",
@ -141,6 +144,7 @@
"Failed to save admin settings": "Failed to save admin settings",
"Featured events": "Featured events",
"Features": "Features",
"Federation": "Federation",
"Find an address": "Find an address",
"Find an instance": "Find an instance",
"Followers": "Followers",
@ -153,6 +157,7 @@
"From the {startDate} to the {endDate}": "From the {startDate} to the {endDate}",
"Gather ⋅ Organize ⋅ Mobilize": "Gather ⋅ Organize ⋅ Mobilize",
"General information": "General information",
"General": "General",
"Getting location": "Getting location",
"Go": "Go",
"Going as {name}": "Going as {name}",
@ -175,6 +180,7 @@
"Identity {displayName} updated": "Identity {displayName} updated",
"If an account with this email exists, we just sent another confirmation email to {email}": "If an account with this email exists, we just sent another confirmation email to {email}",
"If this identity is the only administrator of some groups, you need to delete them before being able to delete this identity.": "If this identity is the only administrator of some groups, you need to delete them before being able to delete this identity.",
"If you want, you may send a message to the event organizer here.": "If you want, you may send a message to the event organizer here.",
"Impossible to login, your email or password seems incorrect.": "Impossible to login, your email or password seems incorrect.",
"In the meantime, please consider that the software is not (yet) finished. More information {onBlog}.": "In the meantime, please consider that the software is not (yet) finished. More information {onBlog}.",
"Installing Mobilizon will allow communities to free themselves from the services of tech giants by creating <b>their own event platform</b>.": "Installing Mobilizon will allow communities to free themselves from the services of tech giants by creating <b>their own event platform</b>.",
@ -183,6 +189,7 @@
"Instance Terms Source": "Instance Terms Source",
"Instance Terms URL": "Instance Terms URL",
"Instance Terms": "Instance Terms",
"Instance settings": "Instance settings",
"Instances": "Instances",
"Join {instance}, a Mobilizon instance": "Join {instance}, a Mobilizon instance",
"Last published event": "Last published event",
@ -204,11 +211,14 @@
"Manage participations": "Manage participations",
"Mark as resolved": "Mark as resolved",
"Members": "Members",
"Message": "Message",
"Mobilizon is a federated network. You can interact with this event from a different server.": "Mobilizon is a federated network. You can interact with this event from a different server.",
"Mobilizon is a free/libre software that will allow communities to create <b>their own spaces</b> to publish events in order to better emancipate themselves from tech giants.": "Mobilizon is a free/libre software that will allow communities to create <b>their own spaces</b> to publish events in order to better emancipate themselves from tech giants.",
"Mobilizon is under development, we will add new features to this site during regular updates, until the release of <b>version 1 of the software in the first half of 2020</b>.": "Mobilizon is under development, we will add new features to this site during regular updates, until the release of <b>version 1 of the software in the first half of 2020</b>.",
"Mobilizons licence": "Mobilizons licence",
"Moderated comments (shown after approval)": "Moderated comments (shown after approval)",
"Moderation log": "Moderation log",
"Moderation": "Moderation",
"My account": "My account",
"My events": "My events",
"My identities": "My identities",
@ -216,6 +226,8 @@
"New email": "New email",
"New note": "New note",
"New password": "New password",
"New profile": "New profile",
"Next page": "Next page",
"No actors found": "No actors found",
"No address defined": "No address defined",
"No closed reports yet": "No closed reports yet",
@ -229,11 +241,17 @@
"No instance to approve|Approve instance|Approve {number} instances": "No instance to approve|Approve instance|Approve {number} instances",
"No instance to reject|Reject instance|Reject {number} instances": "No instance to reject|Reject instance|Reject {number} instances",
"No instance to remove|Remove instance|Remove {number} instances": "No instances to remove|Remove instance|Remove {number} instances",
"No message": "No message",
"No notification settings yet": "No notification settings yet",
"No open reports yet": "No open reports yet",
"No participant to approve|Approve participant|Approve {number} participants": "No participant to approve|Approve participant|Approve {number} participants",
"No participant to reject|Reject participant|Reject {number} participants": "No participant to reject|Reject participant|Reject {number} participants",
"No preferences yet": "No preferences yet",
"No resolved reports yet": "No resolved reports yet",
"No results for \"{queryText}\"": "No results for \"{queryText}\"",
"No user account with this email was found. Maybe you made a typo?": "No user account with this email was found. Maybe you made a typo?",
"Notes": "Notes",
"Notifications": "Notifications",
"Number of places": "Number of places",
"OK": "OK",
"Old password": "Old password",
@ -254,12 +272,15 @@
"Otherwise this identity will just be removed from the group administrators.": "Otherwise this identity will just be removed from the group administrators.",
"Page limited to my group (asks for auth)": "Page limited to my group (asks for auth)",
"Page not found": "Page not found",
"Page": "Page",
"Participant already was rejected.": "Participant already was rejected.",
"Participant has already been approved as participant.": "Participant has already been approved as participant.",
"Participant": "Participant",
"Participants": "Participants",
"Participate using your email address": "Participate using your email address",
"Participate": "Participate",
"Participation approval": "Participation approval",
"Participation confirmation": "Participation confirmation",
"Participation requested!": "Participation requested!",
"Password (confirmation)": "Password (confirmation)",
"Password reset": "Password reset",
@ -276,9 +297,12 @@
"Post a comment": "Post a comment",
"Post a reply": "Post a reply",
"Postal Code": "Postal Code",
"Preferences": "Preferences",
"Previous page": "Previous page",
"Privacy Policy": "Privacy Policy",
"Private event": "Private event",
"Private feeds": "Private feeds",
"Profiles": "Profiles",
"Public RSS/Atom Feed": "Public RSS/Atom Feed",
"Public comment moderation": "Public comment moderation",
"Public event": "Public event",
@ -316,6 +340,7 @@
"Reset my password": "Reset my password",
"Resolved": "Resolved",
"Resource provided is not an URL": "Resource provided is not an URL",
"Role": "Role",
"Save draft": "Save draft",
"Save": "Save",
"Search events, groups, etc.": "Search events, groups, etc.",
@ -350,7 +375,9 @@
"The event has been published": "The event has been published",
"The event has been updated and published": "The event has been updated and published",
"The event has been updated": "The event has been updated",
"The event organiser has chosen to validate manually participations. Do you want to add a little note to explain why you want to participate to this event?": "The event organiser has chosen to validate manually participations. Do you want to add a little note to explain why you want to participate to this event?",
"The event organizer didn't add any description.": "The event organizer didn't add any description.",
"The event organizer manually approves participations. Since you've chosen to participate without an account, please explain why you want to participate to this event.": "The event organizer manually approves participations. Since you've chosen to participate without an account, please explain why you want to participate to this event.",
"The event title will be ellipsed.": "The event title will be ellipsed.",
"The new email doesn't seem to be valid": "The new email doesn't seem to be valid",
"The new email must be different": "The new email must be different",
@ -406,7 +433,6 @@
"Website / URL": "Website / URL",
"Welcome back {username}!": "Welcome back {username}!",
"Welcome back!": "Welcome back!",
"Welcome on your administration panel": "Welcome on your administration panel",
"Welcome to Mobilizon, {username}!": "Welcome to Mobilizon, {username}!",
"Who can view this event and participate": "Who can view this event and participate",
"World map": "World map",
@ -466,17 +492,5 @@
"{count} requests waiting": "{count} requests waiting",
"{license} guarantees {respect} of the people who will use it. Since {source}, anyone can audit it, which guarantees its transparency.": "{license} guarantees {respect} of the people who will use it. Since {source}, anyone can audit it, which guarantees its transparency.",
"© The Mobilizon Contributors {date} - Made with Elixir, Phoenix, VueJS & with some love and some weeks": "© The Mobilizon Contributors {date} - Made with Elixir, Phoenix, VueJS & with some love and some weeks",
"© The OpenStreetMap Contributors": "© The OpenStreetMap Contributors",
"The event organizer manually approves participations. Since you've chosen to participate without an account, please explain why you want to participate to this event.": "The event organizer manually approves participations. Since you've chosen to participate without an account, please explain why you want to participate to this event.",
"If you want, you may send a message to the event organizer here.": "If you want, you may send a message to the event organizer here.",
"Message": "Message",
"Anonymous participant": "Anonymous participant",
"No message": "No message",
"No participant to approve|Approve participant|Approve {number} participants": "No participant to approve|Approve participant|Approve {number} participants",
"No participant to reject|Reject participant|Reject {number} participants": "No participant to reject|Reject participant|Reject {number} participants",
"Role": "Role",
"Participant": "Participant",
"Participation confirmation": "Participation confirmation",
"The event organiser has chosen to validate manually participations. Do you want to add a little note to explain why you want to participate to this event?": "The event organiser has chosen to validate manually participations. Do you want to add a little note to explain why you want to participate to this event?",
"Confirm my participation": "Confirm my participation"
"© The OpenStreetMap Contributors": "© The OpenStreetMap Contributors"
}

View File

@ -3,26 +3,28 @@
"A user-friendly, emancipatory and ethical tool for gathering, organising, and mobilising.": "Un outil convivial, émancipateur et éthique pour se rassembler, s'organiser et se mobiliser.",
"A validation email was sent to {email}": "Un email de validation a été envoyé à {email}",
"Abandon edition": "Abandonner la modification",
"About": "À propos",
"About Mobilizon": "À propos de Mobilizon",
"About this event": "À propos de cet évènement",
"About this instance": "À propos de cette instance",
"About": "À propos",
"Accepted": "Accepté",
"Account settings": "Paramètres du compte",
"Add": "Ajouter",
"Account": "Compte",
"Add a note": "Ajouter une note",
"Add an address": "Ajouter une adresse",
"Add an instance": "Ajouter une instance",
"Add some tags": "Ajouter des tags",
"Add to my calendar": "Ajouter à mon agenda",
"Add": "Ajouter",
"Additional comments": "Commentaires additionnels",
"Admin settings": "Paramètres administrateur",
"Admin settings successfully saved.": "Les paramètres administrateur ont bien été sauvegardés.",
"Admin settings": "Paramètres administrateur",
"Admin": "Admin",
"Administration": "Administration",
"All the places have already been taken": "Toutes les places ont été prises|Une place est encore disponible|{places} places sont encore disponibles",
"Allow all comments": "Autoriser tous les commentaires",
"Allow registrations": "Autoriser les inscriptions",
"An error has occurred.": "Une erreur est survenue.",
"Anonymous participant": "Participant⋅e anonyme",
"Anonymous participants will be asked to confirm their participation through e-mail.": "Les participants anonymes devront confirmer leur participation par email.",
"Anonymous participations": "Participations anonymes",
"Approve": "Approuver",
@ -37,35 +39,35 @@
"Back to previous page": "Retour à la page précédente",
"Before you can login, you need to click on the link inside it to validate your account": "Avant que vous puissiez vous enregistrer, vous devez cliquer sur le lien à l'intérieur pour valider votre compte",
"By @{username}": "Par @{username}",
"Cancel": "Annuler",
"Cancel anonymous participation": "Annuler ma participation anonyme",
"Cancel creation": "Annuler la création",
"Cancel edition": "Annuler la modification",
"Cancel my participation request…": "Annuler ma demande de participation…",
"Cancel my participation…": "Annuler ma participation…",
"Cancel": "Annuler",
"Cancelled: Won't happen": "Annulé : N'aura pas lieu",
"Category": "Catégorie",
"Change": "Modifier",
"Change my email": "Changer mon adresse e-mail",
"Change my identity…": "Changer mon identité…",
"Change my password": "Modifier mon mot de passe",
"Change password": "Modifier mot de passe",
"Change": "Modifier",
"Clear": "Effacer",
"Click to select": "Cliquez pour sélectionner",
"Click to upload": "Cliquez pour uploader",
"Close comments for all (except for admins)": "Fermer les commentaires à tout le monde (excepté les administrateur⋅ices)",
"Close": "Fermé",
"Close comments for all (except for admins)": "Fermer les commentaires à tout le monde (excepté les administrateurs)",
"Closed": "Fermé",
"Comment deleted": "Commentaire supprimé",
"Comment from @{username} reported": "Commentaire de @{username} signalé",
"Comments": "Commentaires",
"Comments have been closed.": "Les commentaires sont fermés.",
"Comments on the event page": "Commentaires sur la page de l'événement",
"Comments": "Commentaires",
"Confirm my participation": "Confirmer ma participation",
"Confirm my particpation": "Confirmer ma participation",
"Confirmed: Will happen": "Confirmé : aura lieu",
"Continue editing": "Continuer la modification",
"Country": "Pays",
"Create": "Créer",
"Create a new event": "Créer un nouvel évènement",
"Create a new group": "Créer un nouveau groupe",
"Create a new identity": "Créer une nouvelle identité",
@ -76,18 +78,19 @@
"Create my profile": "Créer mon profil",
"Create token": "Créer un jeton",
"Create, edit or delete events": "Créer, modifier ou supprimer des évènements",
"Creator": "Créateur",
"Create": "Créer",
"Creator": "Créateur⋅ice",
"Current identity has been changed to {identityName} in order to manage this event.": "L'identité actuelle a été changée à {identityName} pour pouvoir gérer cet évènement.",
"Custom": "Personnel",
"Current page": "Page courante",
"Custom URL": "URL personnalisée",
"Custom text": "Texte personnalisé",
"Custom": "Personnel",
"Dashboard": "Tableau de bord",
"Date": "Date",
"Date and time settings": "Paramètres de date et d'heure",
"Date parameters": "Paramètres de date",
"Default": "Default",
"Date": "Date",
"Default Mobilizon.org terms": "Conditions d'utilisation par défaut de Mobilizon.org",
"Delete": "Supprimer",
"Default": "Default",
"Delete Comment": "Supprimer le commentaire",
"Delete Event": "Supprimer l'évènement",
"Delete account": "Suppression du compte",
@ -98,6 +101,7 @@
"Delete your identity": "Supprimer votre identité",
"Delete {eventTitle}": "Supprimer {eventTitle}",
"Delete {preferredUsername}": "Supprimer {preferredUsername}",
"Delete": "Supprimer",
"Deleting comment": "Suppression du commentaire en cours",
"Deleting event": "Suppression de l'évènement",
"Deleting my account will delete all of my identities.": "Supprimer mon compte supprimera toutes mes identités.",
@ -114,7 +118,7 @@
"Either on the {instance} instance or on another instance.": "Sur l'instance {instance} ou bien sur une autre instance.",
"Either the account is already validated, either the validation token is incorrect.": "Soit le compte est déjà validé, soit le jeton de validation est incorrect.",
"Either the email has already been changed, either the validation token is incorrect.": "Soit l'adresse email a déjà été modifiée, soit le jeton de validation est incorrect.",
"Either the participation has already been validated, either the validation token is incorrect.": "Either the participation has already been validated, either the validation token is incorrect.",
"Either the participation has already been validated, either the validation token is incorrect.": "Soit la participation a déjà été validée, soit le jeton de validation est incorrect.",
"Email": "Email",
"Ends on…": "Se termine le…",
"Enjoy discovering Mobilizon!": "Amusez-vous bien en découvrant Mobilizon !",
@ -124,8 +128,7 @@
"Error while communicating with the server.": "Erreur de communication avec le serveur.",
"Error while saving report.": "Erreur lors de l'enregistrement du signalement.",
"Error while validating account": "Erreur lors de la validation du compte",
"Error while validating participation": "Error lors de la validation de la participation",
"Event": "Événement",
"Error while validating participation": "Erreur lors de la validation de la participation",
"Event already passed": "Événement déjà passé",
"Event cancelled": "Événement annulé",
"Event creation": "Création d'évènement",
@ -136,6 +139,7 @@
"Event to be confirmed": "Événement à confirmer",
"Event {eventTitle} deleted": "Événement {eventTitle} supprimé",
"Event {eventTitle} reported": "Événement {eventTitle} signalé",
"Event": "Événement",
"Events": "Événements",
"Ex: test.mobilizon.org": "Ex : test.mobilizon.org",
"Exclude": "Exclure",
@ -143,6 +147,7 @@
"Failed to save admin settings": "Échec de la sauvegarde des paramètres administrateur",
"Featured events": "Événements à la une",
"Features": "Fonctionnalités",
"Federation": "Fédération",
"Find an address": "Trouver une adresse",
"Find an instance": "Trouver une instance",
"Followers": "Abonnés",
@ -150,11 +155,12 @@
"For instance: London, Taekwondo, Architecture…": "Par exemple : Lyon, Taekwondo, Architecture…",
"Forgot your password ?": "Mot de passe oublié ?",
"From a birthday party with friends and family to a march for climate change, right now, our gatherings are <b>trapped inside the tech giants platforms</b>. How can we organize, how can we click “Attend,” without <b>providing private data</b> to Facebook or <b>locking ourselves up</b> inside MeetUp?": "De lanniversaire entre ami·e·s à une marche pour le climat, aujourdhui, les bonnes raisons de se rassembler sont <b>captées par les géants du web</b>. Comment sorganiser, comment cliquer sur «je participe» sans <b>livrer des données intimes</b> à Facebook ou<b> senfermer</b> dans MeetUp?",
"From the {startDate} at {startTime} to the {endDate}": "Du {startDate} à {startTime} jusqu'au {endDate}",
"From the {startDate} at {startTime} to the {endDate} at {endTime}": "Du {startDate} à {startTime} au {endDate} à {endTime}",
"From the {startDate} at {startTime} to the {endDate}": "Du {startDate} à {startTime} jusqu'au {endDate}",
"From the {startDate} to the {endDate}": "Du {startDate} au {endDate}",
"Gather ⋅ Organize ⋅ Mobilize": "Rassembler ⋅ Organiser ⋅ Mobiliser",
"General information": "Informations générales",
"General": "Général",
"Getting location": "Récupération de la position",
"Go": "Allons-y",
"Going as {name}": "En tant que {name}",
@ -177,20 +183,22 @@
"Identity {displayName} updated": "Identité {displayName} mise à jour",
"If an account with this email exists, we just sent another confirmation email to {email}": "Si un compte avec un tel email existe, nous venons juste d'envoyer un nouvel email de confirmation à {email}",
"If this identity is the only administrator of some groups, you need to delete them before being able to delete this identity.": "Si cette identité est la seule administratrice de certains groupes, vous devez les supprimer avant de pouvoir supprimer cette identité.",
"If you want, you may send a message to the event organizer here.": "Si vous le désirez, vous pouvez laisser un message pour l'organisateur⋅ice de l'événement ci-dessous.",
"Impossible to login, your email or password seems incorrect.": "Impossible de se connecter, votre email ou bien votre mot de passe semble incorrect.",
"In the meantime, please consider that the software is not (yet) finished. More information {onBlog}.": "D'ici là, veuillez considérer que le logiciel n'est pas (encore) fini. Plus d'informations {onBlog}.",
"Installing Mobilizon will allow communities to free themselves from the services of tech giants by creating <b>their own event platform</b>.": "Installer Mobilizon permettra à des collectifs de sémanciper des outils des géants du web en créant <b>leur propre plateforme dévènements</b>.",
"Instance Description": "Description de l'instance",
"Instance Name": "Nom de l'instance",
"Instance Terms": "Conditions générales de l'instance",
"Instance Terms Source": "Source des conditions d'utilisation de l'instance",
"Instance Terms URL": "URL des conditions générales de l'instance",
"Instance Terms": "Conditions générales de l'instance",
"Instance settings": "Paramètres de l'instance",
"Instances": "Instances",
"Join {instance}, a Mobilizon instance": "Rejoignez {instance}, une instance Mobilizon",
"Last published event": "Dernier évènement publié",
"Last week": "La semaine dernière",
"Learn more": "En apprendre plus",
"Learn more about Mobilizon": "En apprendre plus à propos de Mobilizon",
"Learn more": "En apprendre plus",
"Leave event": "Annuler ma participation à l'évènement",
"Leaving event \"{title}\"": "Annuler ma participation à l'évènement",
"Let's create a new common": "Créons un nouveau Common",
@ -200,17 +208,20 @@
"Locality": "Commune",
"Log in": "Se connecter",
"Log out": "Se déconnecter",
"Login": "Se connecter",
"Login on Mobilizon!": "Se connecter sur Mobilizon !",
"Login on {instance}": "Se connecter sur {instance}",
"Login": "Se connecter",
"Manage participations": "Gérer les participations",
"Mark as resolved": "Marquer comme résolu",
"Members": "Membres",
"Message": "Message",
"Mobilizon is a federated network. You can interact with this event from a different server.": "Mobilizon est un réseau fédéré. Vous pouvez interagir avec cet événement depuis un serveur différent.",
"Mobilizon is a free/libre software that will allow communities to create <b>their own spaces</b> to publish events in order to better emancipate themselves from tech giants.": "Mobilizon est un logiciel libre qui permettra à des communautés de <b>créer leurs propres espaces</b> de publication dévènements, afin de mieux sémanciper des géants du web.",
"Mobilizon is under development, we will add new features to this site during regular updates, until the release of <b>version 1 of the software in the first half of 2020</b>.": "Mobilizon est en cours de développement, nous ajouterons de nouvelles fonctionnalités à ce site lors de mises à jour régulières, jusqu'à la publication de <b>la version 1 du logiciel au premier semestre 2020</b>.",
"Mobilizons licence": "La licence de Mobilizon",
"Moderated comments (shown after approval)": "Commentaires modérés (affichés après validation)",
"Moderation log": "Journaux de modération",
"Moderation": "Modération",
"My account": "Mon compte",
"My events": "Mes évènements",
"My identities": "Mes identités",
@ -218,6 +229,8 @@
"New email": "Nouvelle adresse e-mail",
"New note": "Nouvelle note",
"New password": "Nouveau mot de passe",
"New profile": "Nouveau profil",
"Next page": "Page suivante",
"No actors found": "Aucun acteur trouvé",
"No address defined": "Aucune adresse définie",
"No closed reports yet": "Aucun signalement fermé pour le moment",
@ -231,47 +244,56 @@
"No instance to approve|Approve instance|Approve {number} instances": "Aucune instance à approuver|Approuver une instance|Approuver {number} instances",
"No instance to reject|Reject instance|Reject {number} instances": "Aucune instance à rejeter|Rejeter une instance|Rejeter {number} instances",
"No instance to remove|Remove instance|Remove {number} instances": "Pas d'instances à supprimer|Supprimer une instance|Supprimer {number} instances",
"No message": "Pas de message",
"No notification settings yet": "Pas encore de paramètres de notification",
"No open reports yet": "Aucun signalement ouvert pour le moment",
"No participant to approve|Approve participant|Approve {number} participants": "Aucun⋅e participant⋅e à valider|Valider le ou la participant⋅e|Valider {number} participant⋅es",
"No participant to reject|Reject participant|Reject {number} participants": "Aucun⋅e participant⋅e à refuser|Refuser le ou la participant⋅e|Refuser {number} participant⋅es",
"No preferences yet": "Pas encore de préférences",
"No resolved reports yet": "Aucun signalement résolu pour le moment",
"No results for \"{queryText}\"": "Pas de résultats pour « {queryText} »",
"No user account with this email was found. Maybe you made a typo?": "Aucun compte utilisateur trouvé pour cet email. Peut-être avez-vous fait une faute de frappe ?",
"Notes": "Notes",
"Notifications": "Notifications",
"Number of places": "Nombre de places",
"OK": "OK",
"Old password": "Ancien mot de passe",
"On {date}": "Le {date}",
"On {date} ending at {endTime}": "Le {date}, se terminant à {endTime}",
"On {date} from {startTime} to {endTime}": "Le {date} de {startTime} à {endTime}",
"On {date} starting at {startTime}": "Le {date} à partir de {startTime}",
"On {date}": "Le {date}",
"One person is going": "Personne n'y va | Une personne y va | {approved} personnes y vont",
"Only accessible through link and search (private)": "Uniquement accessibles par lien et la recherche (privé)",
"Only alphanumeric characters and underscores are supported.": "Seuls les caractères alphanumériques et les tirets bas sont acceptés.",
"Open": "Ouvert",
"Opened reports": "Signalements ouverts",
"Or": "Ou",
"Organized": "Organisés",
"Organized by {name}": "Organisé par {name}",
"Organized": "Organisés",
"Organizer": "Organisateur⋅ice",
"Other software may also support this.": "D'autres logiciels peuvent également supporter cette fonctionnalité.",
"Otherwise this identity will just be removed from the group administrators.": "Sinon cette identité sera juste supprimée des administrateurs du groupe.",
"Otherwise this identity will just be removed from the group administrators.": "Sinon cette identité sera juste supprimée des administrateur⋅ices du groupe.",
"Page limited to my group (asks for auth)": "Accès limité à mon groupe (demande authentification)",
"Page not found": "Page non trouvée",
"Participant already was rejected.": "Le participant a déjà été refusé.",
"Participant has already been approved as participant.": "Le participant a déjà été approuvé en tant que participant.",
"Page": "Page",
"Participant already was rejected.": "Le ou la participant⋅e a déjà été refusé⋅e.",
"Participant has already been approved as participant.": "Le ou la participant⋅e a déjà été approuvé⋅e en tant que participant⋅e.",
"Participant": "Participant⋅e",
"Participants": "Participant⋅e⋅s",
"Participate": "Participer",
"Participate using your email address": "Participer en utilisant votre adresse email",
"Participate": "Participer",
"Participation approval": "Validation des participations",
"Participation confirmation": "Confirmation de votre participation",
"Participation requested!": "Participation demandée !",
"Password": "Mot de passe",
"Password (confirmation)": "Mot de passe (confirmation)",
"Password change": "Changement de mot de passe",
"Password reset": "Réinitialisation du mot de passe",
"Password": "Mot de passe",
"Past events": "Événements passés",
"Pending": "En attente",
"Pick an identity": "Choisissez une identité",
"Please check your spam folder if you didn't receive the email.": "Merci de vérifier votre dossier des indésirables si vous n'avez pas reçu l'email.",
"Please contact this instance's Mobilizon admin if you think this is a mistake.": "Veuillez contacter l'administrateur de cette instance Mobilizon si vous pensez quil sagit dune erreur.",
"Please contact this instance's Mobilizon admin if you think this is a mistake.": "Veuillez contacter l'administrateur⋅ice de cette instance Mobilizon si vous pensez quil sagit dune erreur.",
"Please enter your password to confirm this action.": "Merci d'entrer votre mot de passe pour confirmer cette action.",
"Please make sure the address is correct and that the page hasn't been moved.": "Assurezvous que ladresse est correcte et que la page na pas été déplacée.",
"Please read the full rules": "Merci de lire les règles complètes",
@ -280,9 +302,12 @@
"Post a comment": "Ajouter un commentaire",
"Post a reply": "Envoyer une réponse",
"Postal Code": "Code postal",
"Preferences": "Préférences",
"Previous page": "Page précédente",
"Privacy Policy": "Politique de confidentialité",
"Private event": "Événement privé",
"Private feeds": "Flux privés",
"Profiles": "Profils",
"Public RSS/Atom Feed": "Flux RSS/Atom public",
"Public comment moderation": "Modération des commentaires publics",
"Public event": "Événement public",
@ -294,37 +319,38 @@
"Read Framasofts statement of intent on the Framablog": "Lire la note dintention de Framasoft sur le Framablog",
"Redirecting to event…": "Redirection vers l'événement…",
"Region": "Région",
"Register": "S'inscrire",
"Register an account on Mobilizon!": "S'inscrire sur Mobilizon !",
"Register for an event by choosing one of your identities": "S'inscrire à un évènement en choisissant une de vos identités",
"Register": "S'inscrire",
"Registration is allowed, anyone can register.": "Les inscriptions sont autorisées, n'importe qui peut s'inscrire.",
"Registration is closed.": "Les inscriptions sont fermées.",
"Registration is currently closed.": "Les inscriptions sont actuellement fermées.",
"Registrations are restricted by whitelisting.": "Les inscriptions sont restreintes par liste blanche.",
"Reject": "Rejeter",
"Rejected": "Rejetés",
"Rejected participations": "Participations rejetées",
"Rejected": "Rejetés",
"Reopen": "Réouvrir",
"Reply": "Répondre",
"Report": "Signalement",
"Report this comment": "Signaler ce commentaire",
"Report this event": "Signaler cet évènement",
"Reported": "Signalée",
"Reported by": "Signalée par",
"Report": "Signalement",
"Reported by someone on {domain}": "Signalé par quelqu'un depuis {domain}",
"Reported by {reporter}": "Signalé par {reporter}",
"Reported by": "Signalée par",
"Reported identity": "Identité signalée",
"Reported": "Signalée",
"Reports": "Signalements",
"Requests": "Requêtes",
"Resend confirmation email": "Envoyer à nouveau l'email de confirmation",
"Reset my password": "Réinitialiser mon mot de passe",
"Resolved": "Résolu",
"Resource provided is not an URL": "La ressource fournie n'est pas une URL",
"Save": "Enregistrer",
"Role": "Rôle",
"Save draft": "Enregistrer le brouillon",
"Search": "Rechercher",
"Save": "Enregistrer",
"Search events, groups, etc.": "Rechercher des évènements, des groupes, etc.",
"Search results: \"{search}\"": "Résultats de recherche : « {search} »",
"Search": "Rechercher",
"Searching…": "Recherche en cours…",
"Send email": "Envoyer un email",
"Send me an email to reset my password": "Envoyez-moi un email pour réinitialiser mon mot de passe",
@ -345,16 +371,18 @@
"Tentative: Will be confirmed later": "Provisoire : sera confirmé plus tard",
"Terms": "Conditions d'utilisation",
"The account's email address was changed. Check your emails to verify it.": "L'adresse email du compte a été modifiée. Vérifiez vos emails pour confirmer le changement.",
"The actual number of participants may differ, as this event is hosted on another instance.": "Le nombre réel de participants peut être différent, car cet événement provient d'une autre instance.",
"The actual number of participants may differ, as this event is hosted on another instance.": "Le nombre réel de participant⋅e⋅s peut être différent, car cet événement provient d'une autre instance.",
"The content came from another server. Transfer an anonymous copy of the report?": "Le contenu provient d'une autre instance. Transférer une copie anonyme du signalement ?",
"The current identity doesn't have any permission on this event. You should probably change it.": "L'identité actuelle n'a pas de permissions sur cet évènement. Vous devriez probablement en changer.",
"The current password is invalid": "Le mot de passe actuel est invalide",
"The draft event has been updated": "L'évènement brouillon a été mis à jour",
"The event has been created as a draft": "L'évènement a été créé en tant que brouillon",
"The event has been published": "L'évènement a été publié",
"The event has been updated": "L'évènement a été mis à jour",
"The event has been updated and published": "L'évènement a été mis à jour et publié",
"The event organizer didn't add any description.": "L'organisateur de l'évènement n'a pas ajouté de description.",
"The event has been updated": "L'évènement a été mis à jour",
"The event organiser has chosen to validate manually participations. Do you want to add a little note to explain why you want to participate to this event?": "L'organisateur⋅ice de l'événement a choisi de valider manuellement les demandes de participation. Voulez-vous ajouter un petit message pour expliquer pourquoi vous souhaitez participer à cet événement ?",
"The event organizer didn't add any description.": "L'organisateur⋅ice de l'évènement n'a pas ajouté de description.",
"The event organizer manually approves participations. Since you've chosen to participate without an account, please explain why you want to participate to this event.": "L'organisateur⋅ice de l'événement valide les participations manuellement. Comme vous avez choisi de participer sans compte, merci d'expliquer pourquoi vous voulez participer à cet événement.",
"The event title will be ellipsed.": "Le titre de l'évènement sera ellipsé.",
"The new email doesn't seem to be valid": "La nouvelle adresse email ne semble pas être valide",
"The new email must be different": "La nouvelle adresse email doit être différente",
@ -365,11 +393,11 @@
"The report will be sent to the moderators of your instance. You can explain why you report this content below.": "Le signalement sera envoyé aux modérateur⋅ices de votre instance. Vous pouvez expliquer pourquoi vous signalez ce contenu ci-dessous.",
"The user account you're trying to login as has not been confirmed yet. Check your email inbox and eventually your spam folder.": "Le compte utilisateur avec lequel vous essayez de vous connectez n'a pas été confirmé. Vérifiez la boite de réception de votre adresse email et éventuellement le dossier des messages indésirables.",
"The {default_terms} will be used. They will be translated in the user's language.": "Les {default_terms} seront utilisées. Elles seront traduites dans la langue de l'utilisateur⋅ice.",
"There are {participants} participants.": "Il n'y a qu'un⋅e participant⋅e. | Il y a {participants} participants.",
"There are {participants} participants.": "Il n'y a qu'un⋅e participant⋅e. | Il y a {participants} participant⋅es.",
"There will be no way to recover your data.": "Il n'y aura aucun moyen de récupérer vos données.",
"These events may interest you": "Ces évènements peuvent vous intéresser",
"This Mobilizon instance and this event organizer allows anonymous participations, but requires validation through email confirmation.": "Cette instance Mobilizon et l'organisateur⋅ice de l'événement autorise les participations anonymes, mais requiert une validation à travers une confirmation par email.",
"This email is already registered as participant for this event": "Cet email est déjà enregistré comme participant pour cet événement",
"This email is already registered as participant for this event": "Cet email est déjà enregistré comme participant⋅e pour cet événement",
"This information is saved only on your computer. Click for details": "Cette information est sauvegardée uniquement sur votre appareil. Cliquez pour plus de details",
"This installation (called “instance“) can easily {interconnect}, thanks to {protocol}.": "Cette installation (appelée “instance“) peut facilement {interconnect}, grâce à {protocol}.",
"This instance isn't opened to registrations, but you can register on other instances.": "Cette instance n'autorise pas les inscriptions, mais vous pouvez vous enregistrer sur d'autres instances.",
@ -385,9 +413,9 @@
"URL": "URL",
"Unfortunately, this instance isn't opened to registrations": "Malheureusement, cette instance n'est pas ouverte aux inscriptions",
"Unfortunately, your participation request was rejected by the organizers.": "Malheureusement, votre demande de participation a été refusée par les organisateur⋅ices.",
"Unknown": "Inconnu",
"Unknown actor": "Acteur inconnu",
"Unknown error.": "Erreur inconnue.",
"Unknown": "Inconnu",
"Unsaved changes": "Modifications non enregistrées",
"Upcoming": "À venir",
"Update event {name}": "Mettre à jour l'évènement {name}",
@ -415,11 +443,11 @@
"Who can view this event and participate": "Qui peut voir cet évènement et y participer",
"World map": "Carte mondiale",
"Write something…": "Écrivez quelque chose…",
"You and one other person are going to this event": "Vous êtes le ou la seule à vous rendre à cet évènement | Vous et une autre personne vous rendez à cet évènement | Vous et {approved} autres personnes vous rendez à cet évènement.",
"You and one other person are going to this event": "Vous êtes le ou la seule à vous rendre à cet évènement | Vous et une autre personne vous rendez à cet évènement | Vous et {approved} autres personnes vous rendez à cet évènement.",
"You are already a participant of this event.": "Vous participez déjà à cet évènement.",
"You are already logged-in.": "Vous êtes déjà connecté.",
"You are participating in this event anonymously": "Vous participez à cet événement anonymement",
"You are participating in this event anonymously but didn't confirm participation": "Vous participez à cet événement anonymement mais vous n'avez pas confirmé votre participation",
"You are participating in this event anonymously": "Vous participez à cet événement anonymement",
"You can add tags by hitting the Enter key or by adding a comma": "Vous pouvez ajouter des tags en appuyant sur la touche Entrée ou bien en ajoutant une virgule",
"You can try another search term or drag and drop the marker on the map": "Vous pouvez essayer avec d'autres termes de recherche ou bien glisser et déposer le marqueur sur la carte",
"You can't remove your last identity.": "Vous ne pouvez pas supprimer votre dernière identité.",
@ -443,9 +471,9 @@
"Your email is being changed": "Votre adresse email est en train d'être modifiée",
"Your email is not whitelisted, you can't register.": "Votre email n'est pas sur la liste blanche, vous ne pouvez pas vous inscrire.",
"Your email will only be used to confirm that you're a real person and send you eventual updates for this event. It will NOT be transmitted to other instances or to the event organizer.": "Votre email sera uniquement utilisé pour confirmer que vous êtes bien une personne réelle et vous envoyer des éventuelles mises à jour pour cet événement. Il ne sera PAS transmis à d'autres instances ou à l'organisateur de l'événement.",
"Your federated identity": "Votre identité fédérée",
"Your federated identity profile@instance": "Votre identité fédérée profil@instance",
"Your local administrator resumed its policy:": "Votre administrateur local a résumé sa politique ainsi :",
"Your federated identity": "Votre identité fédérée",
"Your local administrator resumed its policy:": "Votre administrateur⋅ice local a résumé sa politique ainsi :",
"Your participation has been confirmed": "Votre participation a été confirmée",
"Your participation has been rejected": "Votre participation a été rejettée",
"Your participation has been requested": "Votre participation a été demandée",
@ -472,17 +500,5 @@
"{count} requests waiting": "Une demande en attente|{count} demandes en attente",
"{license} guarantees {respect} of the people who will use it. Since {source}, anyone can audit it, which guarantees its transparency.": "{license} garantit {respect} des personnes qui l'utiliseront. Puisque {source}, il est publiquement auditable, ce qui garantit sa transparence.",
"© The Mobilizon Contributors {date} - Made with Elixir, Phoenix, VueJS & with some love and some weeks": "© Les contributeurs de Mobilizon {date} - Fait avec Elixir, Phoenix, VueJS & et de l'amour et des semaines",
"© The OpenStreetMap Contributors": "© Les Contributeur⋅ices OpenStreetMap",
"The event organizer manually approves participations. Since you've chosen to participate without an account, please explain why you want to participate to this event.": "L'organisateur⋅ice de l'événement valide les participations manuellement. Comme vous avez choisi de participer sans compte, merci d'expliquer pourquoi vous voulez participer à cet événement.",
"If you want, you may send a message to the event organizer here.": "Si vous le désirez, vous pouvez laisser un message pour l'organisateur⋅ice de l'événement ci-dessous.",
"Message": "Message",
"Anonymous participant": "Participant⋅e anonyme",
"No message": "Pas de message",
"No participant to approve|Approve participant|Approve {number} participants": "Aucun⋅e participant⋅e à valider|Valider le ou la participant⋅e|Valider {number} participant⋅es",
"No participant to reject|Reject participant|Reject {number} participants": "Aucun⋅e participant⋅e à refuser|Refuser le ou la participant⋅e|Refuser {number} participant⋅es",
"Role": "Rôle",
"Participant": "Participant⋅e",
"Participation confirmation": "Confirmation de votre participation",
"The event organiser has chosen to validate manually participations. Do you want to add a little note to explain why you want to participate to this event?": "L'organisateur⋅ice de l'événement a choisi de valider manuellement les demandes de participation. Voulez-vous ajouter un petit message pour expliquer pourquoi vous souhaitez participer à cet événement ?",
"Confirm my participation": "Confirmer ma participation"
"© The OpenStreetMap Contributors": "© Les Contributeur⋅ices OpenStreetMap"
}

View File

@ -1,11 +1,3 @@
import Profile from '@/views/Account/Profile.vue';
import MyAccount from '@/views/Account/MyAccount.vue';
import CreateGroup from '@/views/Group/Create.vue';
import Group from '@/views/Group/Group.vue';
import GroupList from '@/views/Group/GroupList.vue';
import { RouteConfig } from 'vue-router';
import EditIdentity from '@/views/Account/children/EditIdentity.vue';
export enum ActorRouteName {
GROUP_LIST = 'GroupList',
GROUP = 'Group',
@ -13,56 +5,4 @@ export enum ActorRouteName {
PROFILE = 'Profile',
}
export enum MyAccountRouteName {
CREATE_IDENTITY = 'CreateIdentity',
UPDATE_IDENTITY = 'UpdateIdentity',
}
export const actorRoutes: RouteConfig[] = [
// {
// path: '/groups',
// name: ActorRouteName.GROUP_LIST,
// component: GroupList,
// meta: { requiredAuth: false },
// },
// {
// path: '/groups/create',
// name: ActorRouteName.CREATE_GROUP,
// component: CreateGroup,
// meta: { requiredAuth: true },
// },
// {
// path: '/~:preferredUsername',
// name: ActorRouteName.GROUP,
// component: Group,
// props: true,
// meta: { requiredAuth: false },
// },
// {
// path: '/@:name',
// name: ActorRouteName.PROFILE,
// component: Profile,
// props: true,
// meta: { requiredAuth: false },
// },
{
path: '/my-account/identity',
component: MyAccount,
props: true,
meta: { requiredAuth: true },
children: [
{
path: 'create',
name: MyAccountRouteName.CREATE_IDENTITY,
component: EditIdentity,
props: (route) => ({ identityName: route.params.identityName, isUpdate: false }),
},
{
path: 'update/:identityName?',
name: MyAccountRouteName.UPDATE_IDENTITY,
component: EditIdentity,
props: (route) => ({ identityName: route.params.identityName, isUpdate: true }),
},
],
},
];

View File

@ -1,51 +0,0 @@
import { RouteConfig } from 'vue-router';
import Dashboard from '@/views/Admin/Dashboard.vue';
import Follows from '@/views/Admin/Follows.vue';
import Followings from '@/components/Admin/Followings.vue';
import Followers from '@/components/Admin/Followers.vue';
import Settings from '@/views/Admin/Settings.vue';
export enum AdminRouteName {
DASHBOARD = 'Dashboard',
RELAYS = 'Relays',
ADMIN_SETTINGS = 'ADMIN_SETTINGS',
RELAY_FOLLOWINGS = 'Followings',
RELAY_FOLLOWERS = 'Followers',
}
export const adminRoutes: RouteConfig[] = [
{
path: '/admin',
name: AdminRouteName.DASHBOARD,
component: Dashboard,
props: true,
meta: { requiredAuth: true },
},
{
path: '/admin/settings',
name: AdminRouteName.ADMIN_SETTINGS,
component: Settings,
props: true,
meta: { requiredAuth: true },
},
{
path: '/admin/relays',
name: AdminRouteName.RELAYS,
redirect: { name: AdminRouteName.RELAY_FOLLOWINGS },
component: Follows,
children: [
{
path: 'followings',
name: AdminRouteName.RELAY_FOLLOWINGS,
component: Followings,
},
{
path: 'followers',
name: AdminRouteName.RELAY_FOLLOWERS,
component: Followers,
},
],
props: true,
meta: { requiredAuth: true },
},
];

View File

@ -5,12 +5,11 @@ import PageNotFound from '@/views/PageNotFound.vue';
import Home from '@/views/Home.vue';
import { UserRouteName, userRoutes } from './user';
import { EventRouteName, eventRoutes } from '@/router/event';
import { ActorRouteName, actorRoutes, MyAccountRouteName } from '@/router/actor';
import { AdminRouteName, adminRoutes } from '@/router/admin';
import { ActorRouteName } from '@/router/actor';
import { ErrorRouteName, errorRoutes } from '@/router/error';
import { authGuardIfNeeded } from '@/router/guards/auth-guard';
import Search from '@/views/Search.vue';
import { ModerationRouteName, moderationRoutes } from '@/router/moderation';
import { SettingsRouteName, settingsRoutes } from '@/router/settings';
Vue.use(Router);
@ -45,9 +44,7 @@ export const RouteName = {
...UserRouteName,
...EventRouteName,
...ActorRouteName,
...MyAccountRouteName,
...AdminRouteName,
...ModerationRouteName,
...SettingsRouteName,
...ErrorRouteName,
};
@ -58,9 +55,7 @@ const router = new Router({
routes: [
...userRoutes,
...eventRoutes,
...actorRoutes,
...adminRoutes,
...moderationRoutes,
...settingsRoutes,
...errorRoutes,
{
path: '/search/:searchTerm/:searchType?',

View File

@ -1,34 +0,0 @@
import { RouteConfig } from 'vue-router';
import ReportList from '@/views/Moderation/ReportList.vue';
import Report from '@/views/Moderation/Report.vue';
import Logs from '@/views/Moderation/Logs.vue';
export enum ModerationRouteName {
REPORTS = 'Reports',
REPORT = 'Report',
LOGS = 'Logs',
}
export const moderationRoutes: RouteConfig[] = [
{
path: '/moderation/reports/:filter?',
name: ModerationRouteName.REPORTS,
component: ReportList,
props: true,
meta: { requiredAuth: true },
},
{
path: '/moderation/report/:reportId',
name: ModerationRouteName.REPORT,
component: Report,
props: true,
meta: { requiredAuth: true },
},
{
path: '/moderation/logs',
name: ModerationRouteName.LOGS,
component: Logs,
props: true,
meta: { requiredAuth: true },
},
];

156
js/src/router/settings.ts Normal file
View File

@ -0,0 +1,156 @@
import { RouteConfig } from 'vue-router';
import Settings from '@/views/Settings.vue';
import AccountSettings from '@/views/Settings/AccountSettings.vue';
import Preferences from '@/views/Settings/Preferences.vue';
import Notifications from '@/views/Settings/Notifications.vue';
import Dashboard from '@/views/Admin/Dashboard.vue';
import AdminSettings from '@/views/Admin/Settings.vue';
import Follows from '@/views/Admin/Follows.vue';
import Followings from '@/components/Admin/Followings.vue';
import Followers from '@/components/Admin/Followers.vue';
import ReportList from '@/views/Moderation/ReportList.vue';
import Report from '@/views/Moderation/Report.vue';
import Logs from '@/views/Moderation/Logs.vue';
import EditIdentity from '@/views/Account/children/EditIdentity.vue';
export enum SettingsRouteName {
SETTINGS = 'SETTINGS',
ACCOUNT_SETTINGS = 'ACCOUNT_SETTINGS',
ACCOUNT_SETTINGS_GENERAL = 'ACCOUNT_SETTINGS_GENERAL',
PREFERENCES = 'PREFERENCES',
NOTIFICATIONS = 'NOTIFICATIONS',
ADMIN = 'ADMIN',
ADMIN_DASHBOARD = 'ADMIN_DASHBOARD',
ADMIN_SETTINGS = 'ADMIN_SETTINGS',
RELAYS = 'Relays',
RELAY_FOLLOWINGS = 'Followings',
RELAY_FOLLOWERS = 'Followers',
MODERATION = 'MODERATION',
REPORTS = 'Reports',
REPORT = 'Report',
REPORT_LOGS = 'Logs',
CREATE_IDENTITY = 'CreateIdentity',
UPDATE_IDENTITY = 'UpdateIdentity',
IDENTITIES = 'IDENTITIES',
}
export const settingsRoutes: RouteConfig[] = [
{
path: '/settings',
component: Settings,
props: true,
meta: { requiredAuth: true },
redirect: { name: SettingsRouteName.ACCOUNT_SETTINGS },
name: SettingsRouteName.SETTINGS,
children: [
{
path: 'account',
name: SettingsRouteName.ACCOUNT_SETTINGS,
redirect: { name: SettingsRouteName.ACCOUNT_SETTINGS_GENERAL },
},
{
path: 'account/general',
name: SettingsRouteName.ACCOUNT_SETTINGS_GENERAL,
component: AccountSettings,
props: true,
meta: { requiredAuth: true },
},
{
path: 'preferences',
name: SettingsRouteName.PREFERENCES,
component: Preferences,
props: true,
meta: { requiredAuth: true },
},
{
path: 'notifications',
name: SettingsRouteName.NOTIFICATIONS,
component: Notifications,
props: true,
meta: { requiredAuth: true },
},
{
path: 'admin',
name: SettingsRouteName.ADMIN,
redirect: { name: SettingsRouteName.ADMIN_DASHBOARD },
},
{
path: 'admin/dashboard',
name: SettingsRouteName.ADMIN_DASHBOARD,
component: Dashboard,
meta: { requiredAuth: true },
},
{
path: 'admin/settings',
name: SettingsRouteName.ADMIN_SETTINGS,
component: AdminSettings,
props: true,
meta: { requiredAuth: true },
},
{
path: 'admin/relays',
name: SettingsRouteName.RELAYS,
redirect: { name: SettingsRouteName.RELAY_FOLLOWINGS },
component: Follows,
children: [
{
path: 'followings',
name: SettingsRouteName.RELAY_FOLLOWINGS,
component: Followings,
},
{
path: 'followers',
name: SettingsRouteName.RELAY_FOLLOWERS,
component: Followers,
},
],
props: true,
meta: { requiredAuth: true },
},
{
path: '/moderation',
name: SettingsRouteName.MODERATION,
redirect: { name: SettingsRouteName.REPORTS },
},
{
path: '/moderation/reports/:filter?',
name: SettingsRouteName.REPORTS,
component: ReportList,
props: true,
meta: { requiredAuth: true },
},
{
path: '/moderation/report/:reportId',
name: SettingsRouteName.REPORT,
component: Report,
props: true,
meta: { requiredAuth: true },
},
{
path: '/moderation/logs',
name: SettingsRouteName.REPORT_LOGS,
component: Logs,
props: true,
meta: { requiredAuth: true },
},
{
path: '/identity',
name: SettingsRouteName.IDENTITIES,
redirect: { name: SettingsRouteName.UPDATE_IDENTITY },
},
{
path: '/identity/create',
name: SettingsRouteName.CREATE_IDENTITY,
component: EditIdentity,
props: (route) => ({ identityName: route.params.identityName, isUpdate: false }),
},
{
path: '/identity/update/:identityName?',
name: SettingsRouteName.UPDATE_IDENTITY,
component: EditIdentity,
props: (route) => ({ identityName: route.params.identityName, isUpdate: true }),
},
],
},
];

View File

@ -7,7 +7,6 @@ import SendPasswordReset from '@/views/User/SendPasswordReset.vue';
import PasswordReset from '@/views/User/PasswordReset.vue';
import { beforeRegisterGuard } from '@/router/guards/register-guard';
import { RouteConfig } from 'vue-router';
import AccountSettings from '@/views/User/AccountSettings.vue';
import EmailValidate from '@/views/User/EmailValidate.vue';
export enum UserRouteName {
@ -18,7 +17,6 @@ export enum UserRouteName {
PASSWORD_RESET = 'PasswordReset',
VALIDATE = 'Validate',
LOGIN = 'Login',
ACCOUNT_SETTINGS = 'ACCOUNT_SETTINGS',
}
export const userRoutes: RouteConfig[] = [
@ -80,10 +78,4 @@ export const userRoutes: RouteConfig[] = [
props: true,
meta: { requiredAuth: false },
},
{
path: '/my-account/settings',
name: UserRouteName.ACCOUNT_SETTINGS,
component: AccountSettings,
meta: { requiredAuth: true },
},
];

View File

@ -0,0 +1,8 @@
import { Route } from 'vue-router';
export interface ISettingMenuSection {
title: string;
to: Route;
items?: ISettingMenuSection[];
parents?: ISettingMenuSection[];
}

View File

@ -2,7 +2,8 @@
$primary: #424056;
$primary-invert: findColorInvert($primary);
$secondary: #ffcc85;
//$secondary: #ffcc85;
$secondary: #ffd599;
$secondary-invert: findColorInvert($secondary);
$success: #0ECCAF;

View File

@ -1,92 +0,0 @@
<template>
<section class="section container">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li class="is-active">
<router-link :to="{ name: RouteName.UPDATE_IDENTITY }" aria-current="page">{{ $t('My account') }}</router-link>
</li>
</ul>
</nav>
<div v-if="currentActor">
<div class="header">
<figure v-if="currentActor.banner" class="image is-3by1">
<img :src="currentActor.banner.url" alt="banner">
</figure>
</div>
<div class="columns">
<div class="identities column is-4">
<identities :currentIdentityName="currentIdentityName" />
<div class="buttons">
<b-button tag="router-link" type="is-secondary" :to="{ name: RouteName.ACCOUNT_SETTINGS }">{{ $t('Account settings') }}</b-button>
</div>
</div>
<div class="column is-8">
<router-view />
</div>
</div>
</div>
</section>
</template>
<style lang="scss">
.header {
padding-bottom: 30px;
}
.identities {
padding-right: 45px;
margin-right: 45px;
.buttons {
margin-top: 1.2rem;
}
}
</style>
<script lang="ts">
import { CURRENT_ACTOR_CLIENT } from '@/graphql/actor';
import { Component, Vue, Watch } from 'vue-property-decorator';
import EventCard from '@/components/Event/EventCard.vue';
import { IPerson } from '@/types/actor';
import Identities from '@/components/Account/Identities.vue';
import { RouteName } from '@/router';
@Component({
components: {
EventCard,
Identities,
},
apollo: {
currentActor: {
query: CURRENT_ACTOR_CLIENT,
},
},
})
export default class MyAccount extends Vue {
currentActor!: IPerson;
currentIdentityName: string | null = null;
RouteName = RouteName;
@Watch('$route.params.identityName', { immediate: true })
async onIdentityParamChanged(val: string) {
await this.redirectIfNoIdentitySelected(val);
this.currentIdentityName = val;
}
private async redirectIfNoIdentitySelected(identityParam?: string) {
if (!!identityParam) return;
if (!!this.currentActor) {
await this.$router.push({ params: { identityName: this.currentActor.preferredUsername } });
}
}
}
</script>
<style lang="scss">
@import "../../variables";
@import "~bulma/sass/utilities/_all";
@import "~bulma/sass/components/dropdown.sass";
</style>

View File

@ -116,7 +116,7 @@ import { CREATE_FEED_TOKEN_ACTOR } from '@/graphql/feed_tokens';
EventCard,
},
})
export default class MyAccount extends Vue {
export default class Profile extends Vue {
@Prop({ type: String, required: true }) name!: string;
person!: IPerson;

View File

@ -1,27 +1,27 @@
<template>
<section class="section container">
<section>
<h1 class="title">{{ $t('Administration') }}</h1>
<div class="tile is-ancestor" v-if="dashboard">
<div class="tile is-vertical is-4">
<div class="tile is-vertical">
<div class="tile">
<div class="tile is-parent is-vertical is-6">
<article class="tile is-child box">
<p class="title">{{ dashboard.numberOfEvents }}</p>
<p class="dashboard-number">{{ dashboard.numberOfEvents }}</p>
<p>{{ $t('Published events')}}</p>
</article>
<article class="tile is-child box">
<p class="title">{{ dashboard.numberOfComments}}</p>
<p class="dashboard-number">{{ dashboard.numberOfComments}}</p>
<p>{{ $t('Comments')}}</p>
</article>
</div>
<div class="tile is-parent is-vertical">
<article class="tile is-child box">
<p class="title">{{ dashboard.numberOfUsers }}</p>
<p class="dashboard-number">{{ dashboard.numberOfUsers }}</p>
<p>{{ $t('Users')}}</p>
</article>
<router-link :to="{ name: RouteName.REPORTS}">
<article class="tile is-child box">
<p class="title">{{ dashboard.numberOfReports }}</p>
<p class="dashboard-number">{{ dashboard.numberOfReports }}</p>
<p>{{ $t('Opened reports')}}</p>
</article>
</router-link>
@ -30,7 +30,7 @@
<div class="tile is-parent" v-if="dashboard.lastPublicEventPublished">
<router-link :to="{ name: RouteName.EVENT, params: { uuid: dashboard.lastPublicEventPublished.uuid } }">
<article class="tile is-child box">
<p class="title">{{ $t('Last published event') }}</p>
<p class="dashboard-number">{{ $t('Last published event') }}</p>
<p class="subtitle">{{ dashboard.lastPublicEventPublished.title }}</p>
<figure class="image is-4by3" v-if="dashboard.lastPublicEventPublished.picture">
<img :src="dashboard.lastPublicEventPublished.picture.url" />
@ -38,33 +38,6 @@
</article>
</router-link>
</div>
<div class="tile is-parent">
<router-link :to="{ name: RouteName.RELAYS }">
<article class="tile is-child box">
<span>{{ $t('Instances') }}</span>
</article>
</router-link>
</div>
<div class="tile is-parent">
<router-link :to="{ name: RouteName.ADMIN_SETTINGS }">
<article class="tile is-child box">
<span>{{ $t('Settings') }}</span>
</article>
</router-link>
</div>
</div>
<div class="tile is-parent">
<article class="tile is-child box">
<div class="content">
<p class="title">{{ $t('Welcome on your administration panel') }}</p>
<p class="subtitle">With even more content</p>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper diam at erat pulvinar, at pulvinar felis blandit. Vestibulum volutpat tellus diam, consequat gravida libero rhoncus ut. Morbi maximus, leo sit amet vehicula eleifend, nunc dui porta orci, quis semper odio felis ut quam.</p>
<p>Suspendisse varius ligula in molestie lacinia. Maecenas varius eget ligula a sagittis. Pellentesque interdum, nisl nec interdum maximus, augue diam porttitor lorem, et sollicitudin felis neque sit amet erat. Maecenas imperdiet felis nisi, fringilla luctus felis hendrerit sit amet. Aenean vitae gravida diam, finibus dignissim turpis. Sed eget varius ligula, at volutpat tortor.</p>
<p>Integer sollicitudin, tortor a mattis commodo, velit urna rhoncus erat, vitae congue lectus dolor consequat libero. Donec leo ligula, maximus et pellentesque sed, gravida a metus. Cras ullamcorper a nunc ac porta. Aliquam ut aliquet lacus, quis faucibus libero. Quisque non semper leo.</p>
</div>
</div>
</article>
</div>
</div>
</section>
@ -93,3 +66,12 @@ export default class Dashboard extends Vue {
RouteName = RouteName;
}
</script>
<style lang="scss" scoped>
.dashboard-number {
color: #3C376E;
font-size: 40px;
font-weight: 700;
line-height: 1.125;
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<section class="section container">
<section>
<h1 class="title">{{ $t('Instances') }}</h1>
<div class="tabs is-boxed">
<ul>

View File

@ -1,11 +1,5 @@
<template>
<section class="container section" v-if="adminSettings">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li><router-link :to="{ name: RouteName.DASHBOARD }">{{ $t('Dashboard') }}</router-link></li>
<li class="is-active"><router-link :to="{ name: RouteName.ADMIN_SETTINGS }" aria-current="page">{{ $t('Admin settings') }}</router-link></li>
</ul>
</nav>
<section v-if="adminSettings">
<form @submit.prevent="updateSettings">
<b-field :label="$t('Instance Name')">
<b-input v-model="adminSettings.instanceName" />

View File

@ -1,11 +1,5 @@
<template>
<section class="section container">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li><router-link :to="{ name: RouteName.DASHBOARD }">Dashboard</router-link></li>
<li class="is-active"><router-link :to="{ name: RouteName.LOGS }" aria-current="page">Logs</router-link></li>
</ul>
</nav>
<section>
<ul v-if="actionLogs.length > 0">
<li v-for="log in actionLogs">
<div class="box">

View File

@ -1,14 +1,7 @@
<template>
<section class="container section">
<section>
<b-message title="Error" type="is-danger" v-for="error in errors" :key="error">{{ error }}</b-message>
<div class="container" v-if="report">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li><router-link :to="{ name: RouteName.DASHBOARD }">{{ $t('Dashboard') }}</router-link></li>
<li><router-link :to="{ name: RouteName.REPORTS }">{{ $t('Reports') }}</router-link></li>
<li class="is-active"><router-link :to="{ name: RouteName.REPORT, params: { reportId: this.report.id} }" aria-current="page">{{ $t('Report') }}</router-link></li>
</ul>
</nav>
<div class="buttons">
<b-button v-if="report.status !== ReportStatusEnum.RESOLVED" @click="updateReport(ReportStatusEnum.RESOLVED)" type="is-primary">{{ $t('Mark as resolved') }}</b-button>
<b-button v-if="report.status !== ReportStatusEnum.OPEN" @click="updateReport(ReportStatusEnum.OPEN)" type="is-success">{{ $t('Reopen') }}</b-button>

View File

@ -1,11 +1,5 @@
<template>
<section class="container section">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li><router-link :to="{ name: RouteName.DASHBOARD }">{{ $t('Dashboard') }}</router-link></li>
<li class="is-active"><router-link :to="{ name: RouteName.REPORTS }" aria-current="page">{{ $t('Reports') }}</router-link></li>
</ul>
</nav>
<section>
<b-field>
<b-radio-button v-model="filterReports"
:native-value="ReportStatusEnum.OPEN">

166
js/src/views/Settings.vue Normal file
View File

@ -0,0 +1,166 @@
<template>
<aside class="section container">
<h1 class="title">{{ $t('Settings') }}</h1>
<div class="columns">
<SettingsMenu class="column is-one-quarter-desktop" :menu="menu" />
<div class="column">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li v-for="route in routes.get($route.name)" :class="{ 'is-active': route.to.name === $route.name }"><router-link :to="{ name: route.to.name }">{{ route.title }}</router-link></li>
</ul>
</nav>
<router-view />
</div>
</div>
</aside>
</template>
<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator';
import SettingsMenu from '@/components/Settings/SettingsMenu.vue';
import { RouteName } from '@/router';
import { ISettingMenuSection } from '@/types/setting-menu.model';
import { Route } from 'vue-router';
import { IPerson, Person } from '@/types/actor';
import { IDENTITIES } from '@/graphql/actor';
@Component({
components: { SettingsMenu },
apollo: {
identities: {
query: IDENTITIES,
update: (data) => { return data.identities.map(identity => new Person(identity)); },
},
},
})
export default class Settings extends Vue {
RouteName = RouteName;
menu: ISettingMenuSection[] = [];
identities!: IPerson[];
newIdentity!: ISettingMenuSection;
mounted() {
this.newIdentity = {
title: this.$t('New profile') as string,
to: { name: RouteName.CREATE_IDENTITY } as Route,
};
this.menu = [
{
title: this.$t('Account') as string,
to: { name: RouteName.ACCOUNT_SETTINGS } as Route,
items: [
{
title: this.$t('General') as string,
to: { name: RouteName.ACCOUNT_SETTINGS_GENERAL } as Route,
},
{
title: this.$t('Preferences') as string,
to: { name: RouteName.PREFERENCES } as Route,
},
{
title: this.$t('Notifications') as string,
to: { name: RouteName.NOTIFICATIONS } as Route,
},
],
},
{
title: this.$t('Profiles') as string,
to: { name: RouteName.IDENTITIES } as Route,
items: [this.newIdentity],
},
{
title: this.$t('Moderation') as string,
to: { name: RouteName.MODERATION } as Route,
items: [
{
title: this.$t('Reports') as string,
to: { name: RouteName.REPORTS } as Route,
items: [
{
title: this.$t('Report') as string,
to: { name: RouteName.REPORT } as Route,
},
],
},
{
title: this.$t('Moderation log') as string,
to: { name: RouteName.REPORT_LOGS } as Route,
},
],
},
{
title: this.$t('Admin') as string,
to: { name: RouteName.ADMIN } as Route,
items: [
{
title: this.$t('Dashboard') as string,
to: { name: RouteName.ADMIN_DASHBOARD } as Route,
},
{
title: this.$t('Instance settings') as string,
to: { name: RouteName.ADMIN_SETTINGS } as Route,
},
{
title: this.$t('Federation') as string,
to: { name: RouteName.RELAYS } as Route,
items: [
{
title: this.$t('Followings') as string,
to: { name: RouteName.RELAY_FOLLOWINGS } as Route,
},
{
title: this.$t('Followers') as string,
to: { name: RouteName.RELAY_FOLLOWERS } as Route,
},
],
},
],
},
];
}
@Watch('identities')
updateIdentities(identities) {
if (!identities) return;
if (!this.menu[1].items) return;
this.menu[1].items = [];
this.menu[1].items.push(...identities.map((identity: IPerson) => {
return {
to: { name: RouteName.UPDATE_IDENTITY, params: { identityName: identity.preferredUsername } } as unknown as Route,
title: `@${identity.preferredUsername}`,
};
}));
this.menu[1].items.push(this.newIdentity);
}
get routes(): Map<string, Route[]> {
return this.getPath(this.menu);
}
getPath(object: ISettingMenuSection[]) {
function iter(menu: ISettingMenuSection[]|ISettingMenuSection, acc: ISettingMenuSection[]) {
if (Array.isArray(menu)) {
return menu.forEach((item: ISettingMenuSection) => {
iter(item, acc.concat(item));
});
}
if (menu.items && menu.items.length > 0) {
return menu.items.forEach((item: ISettingMenuSection) => {
iter(item, acc.concat(item));
});
}
result.set(menu.to.name, acc);
}
const result = new Map();
iter(object, []);
return result;
}
}
</script>
<style lang="scss" scoped>
aside.section {
padding-top: 1rem;
}
</style>

View File

@ -1,11 +1,5 @@
<template>
<section class="section container">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li><router-link :to="{ name: RouteName.UPDATE_IDENTITY }">{{ $t('My account') }}</router-link></li>
<li class="is-active"><router-link :to="{ name: RouteName.ACCOUNT_SETTINGS }" aria-current="page">{{ $t('Account settings') }}</router-link></li>
</ul>
</nav>
<section>
<div class="setting-title">
<h2>{{ $t('Email') }}</h2>
</div>

View File

@ -0,0 +1,13 @@
<template>
<div>
<h2 class="subtitle">{{ $t('No notification settings yet') }}</h2>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component
export default class Notifications extends Vue {
}
</script>

View File

@ -0,0 +1,13 @@
<template>
<div>
<h2 class="subtitle">{{ $t('No preferences yet') }}</h2>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component
export default class Preferences extends Vue {
}
</script>