Merge branch 'more-fixes' into 'master'
Even more fixes See merge request framasoft/mobilizon!472
This commit is contained in:
commit
061f51447e
@ -7,31 +7,11 @@
|
|||||||
<date-calendar-icon :date="participation.event.beginsOn" />
|
<date-calendar-icon :date="participation.event.beginsOn" />
|
||||||
</div>
|
</div>
|
||||||
<router-link :to="{ name: RouteName.EVENT, params: { uuid: participation.event.uuid } }">
|
<router-link :to="{ name: RouteName.EVENT, params: { uuid: participation.event.uuid } }">
|
||||||
<h2 class="title">{{ participation.event.title }}</h2>
|
<h3 class="title">{{ participation.event.title }}</h3>
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="participation-actor has-text-grey">
|
<div class="participation-actor has-text-grey">
|
||||||
<span
|
|
||||||
v-if="
|
|
||||||
participation.event.physicalAddress && participation.event.physicalAddress.locality
|
|
||||||
"
|
|
||||||
>{{ participation.event.physicalAddress.locality }} -</span
|
|
||||||
>
|
|
||||||
<span>
|
<span>
|
||||||
<span>
|
|
||||||
{{
|
|
||||||
$t("Organized by {name}", {
|
|
||||||
name: participation.event.organizerActor.displayName(),
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
<span v-if="participation.role === ParticipantRole.PARTICIPANT">
|
|
||||||
{{ $t("Going as {name}", { name: participation.actor.displayName() }) }}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="columns">
|
|
||||||
<span class="column is-narrow">
|
|
||||||
<b-icon icon="earth" v-if="participation.event.visibility === EventVisibility.PUBLIC" />
|
<b-icon icon="earth" v-if="participation.event.visibility === EventVisibility.PUBLIC" />
|
||||||
<b-icon
|
<b-icon
|
||||||
icon="link"
|
icon="link"
|
||||||
@ -42,7 +22,42 @@
|
|||||||
v-else-if="participation.event.visibility === EventVisibility.PRIVATE"
|
v-else-if="participation.event.visibility === EventVisibility.PRIVATE"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span class="column is-narrow participant-stats">
|
<span
|
||||||
|
v-if="
|
||||||
|
participation.event.physicalAddress && participation.event.physicalAddress.locality
|
||||||
|
"
|
||||||
|
>{{ participation.event.physicalAddress.locality }} -</span
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<i18n tag="span" path="Organized by {name}">
|
||||||
|
<popover-actor-card
|
||||||
|
slot="name"
|
||||||
|
:actor="participation.event.organizerActor"
|
||||||
|
:inline="true"
|
||||||
|
>
|
||||||
|
{{ participation.event.organizerActor.displayName() }}
|
||||||
|
</popover-actor-card>
|
||||||
|
</i18n>
|
||||||
|
<i18n
|
||||||
|
v-if="participation.role === ParticipantRole.PARTICIPANT"
|
||||||
|
path="Going as {name}"
|
||||||
|
tag="span"
|
||||||
|
>
|
||||||
|
<popover-actor-card slot="name" :actor="participation.actor" :inline="true">
|
||||||
|
{{ participation.actor.displayName() }}
|
||||||
|
</popover-actor-card>
|
||||||
|
</i18n>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="participant-stats"
|
||||||
|
v-if="
|
||||||
|
![ParticipantRole.PARTICIPANT, ParticipantRole.NOT_APPROVED].includes(
|
||||||
|
participation.role
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>
|
||||||
<span v-if="participation.event.options.maximumAttendeeCapacity !== 0">
|
<span v-if="participation.event.options.maximumAttendeeCapacity !== 0">
|
||||||
{{
|
{{
|
||||||
$t("{approved} / {total} seats", {
|
$t("{approved} / {total} seats", {
|
||||||
@ -176,6 +191,7 @@ import { CURRENT_ACTOR_CLIENT } from "../../graphql/actor";
|
|||||||
import EventMixin from "../../mixins/event";
|
import EventMixin from "../../mixins/event";
|
||||||
import RouteName from "../../router/name";
|
import RouteName from "../../router/name";
|
||||||
import { changeIdentity } from "../../utils/auth";
|
import { changeIdentity } from "../../utils/auth";
|
||||||
|
import PopoverActorCard from "../Account/PopoverActorCard.vue";
|
||||||
|
|
||||||
const defaultOptions: IEventCardOptions = {
|
const defaultOptions: IEventCardOptions = {
|
||||||
hideDate: true,
|
hideDate: true,
|
||||||
@ -187,6 +203,7 @@ const defaultOptions: IEventCardOptions = {
|
|||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
DateCalendarIcon,
|
DateCalendarIcon,
|
||||||
|
PopoverActorCard,
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
currentActor: {
|
currentActor: {
|
||||||
|
@ -206,6 +206,7 @@ export const LOGGED_USER_PARTICIPATIONS = gql`
|
|||||||
preferredUsername
|
preferredUsername
|
||||||
name
|
name
|
||||||
domain
|
domain
|
||||||
|
summary
|
||||||
avatar {
|
avatar {
|
||||||
url
|
url
|
||||||
}
|
}
|
||||||
@ -226,6 +227,7 @@ export const LOGGED_USER_PARTICIPATIONS = gql`
|
|||||||
preferredUsername
|
preferredUsername
|
||||||
name
|
name
|
||||||
domain
|
domain
|
||||||
|
summary
|
||||||
avatar {
|
avatar {
|
||||||
url
|
url
|
||||||
}
|
}
|
||||||
|
@ -184,6 +184,11 @@ export const LOGS = gql`
|
|||||||
domain
|
domain
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
|
... on User {
|
||||||
|
id
|
||||||
|
email
|
||||||
|
confirmedAt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
insertedAt
|
insertedAt
|
||||||
}
|
}
|
||||||
|
@ -256,7 +256,7 @@
|
|||||||
"On {date} from {startTime} to {endTime}": "On {date} from {startTime} to {endTime}",
|
"On {date} from {startTime} to {endTime}": "On {date} from {startTime} to {endTime}",
|
||||||
"On {date} starting at {startTime}": "On {date} starting at {startTime}",
|
"On {date} starting at {startTime}": "On {date} starting at {startTime}",
|
||||||
"On {date}": "On {date}",
|
"On {date}": "On {date}",
|
||||||
"Only accessible through link and search (private)": "Only accessible through link and search (private)",
|
"Only accessible through link (private)": "Only accessible through link (private)",
|
||||||
"Only alphanumeric characters and underscores are supported.": "Only alphanumeric characters and underscores are supported.",
|
"Only alphanumeric characters and underscores are supported.": "Only alphanumeric characters and underscores are supported.",
|
||||||
"Open": "Open",
|
"Open": "Open",
|
||||||
"Opened reports": "Opened reports",
|
"Opened reports": "Opened reports",
|
||||||
@ -581,12 +581,12 @@
|
|||||||
"Every hour": "Every hour",
|
"Every hour": "Every hour",
|
||||||
"Every day": "Every day",
|
"Every day": "Every day",
|
||||||
"report #{report_number}": "report #{report_number}",
|
"report #{report_number}": "report #{report_number}",
|
||||||
"{actor} closed {report}": "{actor} closed {report}",
|
"{moderator} closed {report}": "{moderator} closed {report}",
|
||||||
"a non-existent report": "a non-existent report",
|
"a non-existent report": "a non-existent report",
|
||||||
"{actor} reopened {report}": "{actor} reopened {report}",
|
"{moderator} reopened {report}": "{moderator} reopened {report}",
|
||||||
"{actor} marked {report} as resolved": "{actor} marked {report} as resolved",
|
"{moderator} marked {report} as resolved": "{moderator} marked {report} as resolved",
|
||||||
"{actor} added a note on {report}": "{actor} added a note on {report}",
|
"{moderator} added a note on {report}": "{moderator} added a note on {report}",
|
||||||
"{actor} deleted an event named \"{title}\"": "{actor} deleted an event named \"{title}\"",
|
"{moderator} deleted an event named \"{title}\"": "{moderator} deleted an event named \"{title}\"",
|
||||||
"If the direction given by the development team does not suit you, you have the legal right to create your own version of the software, with your own governance choices.": "If the direction given by the development team does not suit you, you have the legal right to create your own version of the software, with your own governance choices.",
|
"If the direction given by the development team does not suit you, you have the legal right to create your own version of the software, with your own governance choices.": "If the direction given by the development team does not suit you, you have the legal right to create your own version of the software, with your own governance choices.",
|
||||||
"change the world, one byte at a time": "change the world, one byte at a time",
|
"change the world, one byte at a time": "change the world, one byte at a time",
|
||||||
"Concieved with care for humans": "Concieved with care for humans",
|
"Concieved with care for humans": "Concieved with care for humans",
|
||||||
@ -623,7 +623,7 @@
|
|||||||
"Participations": "Participations",
|
"Participations": "Participations",
|
||||||
"Nothing to see here": "Nothing to see here",
|
"Nothing to see here": "Nothing to see here",
|
||||||
"Not confirmed": "Not confirmed",
|
"Not confirmed": "Not confirmed",
|
||||||
"{actor} suspended profile {profile}": "{actor} suspended profile {profile}",
|
"{moderator} suspended profile {profile}": "{moderator} suspended profile {profile}",
|
||||||
"Suspend": "Suspend",
|
"Suspend": "Suspend",
|
||||||
"Unsuspend": "Unsuspend",
|
"Unsuspend": "Unsuspend",
|
||||||
"None": "None",
|
"None": "None",
|
||||||
@ -642,5 +642,7 @@
|
|||||||
"I agree to the {instanceRules} and {termsOfService}": "I agree to the {instanceRules} and {termsOfService}",
|
"I agree to the {instanceRules} and {termsOfService}": "I agree to the {instanceRules} and {termsOfService}",
|
||||||
"This email is already used.": "This email is already used.",
|
"This email is already used.": "This email is already used.",
|
||||||
"Powered by {mobilizon}. © 2018 - {date} The Mobilizon Contributors - Made with the financial support of {contributors}.": "Powered by {mobilizon}. © 2018 - {date} The Mobilizon Contributors - Made with the financial support of {contributors}.",
|
"Powered by {mobilizon}. © 2018 - {date} The Mobilizon Contributors - Made with the financial support of {contributors}.": "Powered by {mobilizon}. © 2018 - {date} The Mobilizon Contributors - Made with the financial support of {contributors}.",
|
||||||
"more than 1360 contributors": "more than 1360 contributors"
|
"more than 1360 contributors": "more than 1360 contributors",
|
||||||
|
"{moderator} has unsuspended profile {profile}": "{moderator} has unsuspended profile {profile}",
|
||||||
|
"{moderator} has deleted user {user}": "{moderator} has deleted user {user}"
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,7 @@
|
|||||||
"On {date} starting at {startTime}": "Le {date} à partir de {startTime}",
|
"On {date} starting at {startTime}": "Le {date} à partir de {startTime}",
|
||||||
"One person is going": "Personne n'y va | Une personne y va | {approved} personnes y vont",
|
"One person is going": "Personne n'y va | Une personne y va | {approved} personnes y vont",
|
||||||
"Ongoing tasks": "Tâches en cours",
|
"Ongoing tasks": "Tâches en cours",
|
||||||
"Only accessible through link and search (private)": "Uniquement accessibles par lien et la recherche (privé)",
|
"Only accessible through link (private)": "Uniquement accessible par lien (privé)",
|
||||||
"Only alphanumeric characters and underscores are supported.": "Seuls les caractères alphanumériques et les tirets bas sont acceptés.",
|
"Only alphanumeric characters and underscores are supported.": "Seuls les caractères alphanumériques et les tirets bas sont acceptés.",
|
||||||
"Open": "Ouvert",
|
"Open": "Ouvert",
|
||||||
"Opened reports": "Signalements ouverts",
|
"Opened reports": "Signalements ouverts",
|
||||||
@ -603,12 +603,12 @@
|
|||||||
"Every hour": "À chaque heure",
|
"Every hour": "À chaque heure",
|
||||||
"Every day": "Chaque jour",
|
"Every day": "Chaque jour",
|
||||||
"report #{report_number}": "le signalement #{report_number}",
|
"report #{report_number}": "le signalement #{report_number}",
|
||||||
"{actor} closed {report}": "{actor} a fermé {report}",
|
"{moderator} closed {report}": "{moderator} a fermé {report}",
|
||||||
"a non-existent report": "un signalement non-existant",
|
"a non-existent report": "un signalement non-existant",
|
||||||
"{actor} reopened {report}": "{actor} a réouvert {report}",
|
"{moderator} reopened {report}": "{moderator} a réouvert {report}",
|
||||||
"{actor} marked {report} as resolved": "{actor} a marqué {report} comme résolu",
|
"{moderator} marked {report} as resolved": "{moderator} a marqué {report} comme résolu",
|
||||||
"{actor} added a note on {report}": "{actor} a ajouté une note sur {report}",
|
"{moderator} added a note on {report}": "{moderator} a ajouté une note sur {report}",
|
||||||
"{actor} deleted an event named \"{title}\"": "{actor} a supprimé un événement nommé \"{title}\"",
|
"{moderator} deleted an event named \"{title}\"": "{moderator} a supprimé un événement nommé \"{title}\"",
|
||||||
"If the direction given by the development team does not suit you, you have the legal right to create your own version of the software, with your own governance choices.": "Si la direction donnée par l’équipe de développement ne vous convient pas, vous avez légalement le droit de créer votre version du logiciel avec vos propres choix de gouvernance.",
|
"If the direction given by the development team does not suit you, you have the legal right to create your own version of the software, with your own governance choices.": "Si la direction donnée par l’équipe de développement ne vous convient pas, vous avez légalement le droit de créer votre version du logiciel avec vos propres choix de gouvernance.",
|
||||||
"change the world, one byte at a time": "changer le monde, un octet à la fois",
|
"change the world, one byte at a time": "changer le monde, un octet à la fois",
|
||||||
"Concieved with care for humans": "Conçu avec soin pour les humains",
|
"Concieved with care for humans": "Conçu avec soin pour les humains",
|
||||||
@ -621,7 +621,7 @@
|
|||||||
"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 fall 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 à l'automne 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 fall 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 à l'automne 2020</b>.",
|
||||||
"To activate more notifications, head over to the notification settings.": "Pour activer plus de notifications, rendez-vous dans vos paramètres de notification.",
|
"To activate more notifications, head over to the notification settings.": "Pour activer plus de notifications, rendez-vous dans vos paramètres de notification.",
|
||||||
"Manage my notifications": "Gérer mes notifications",
|
"Manage my notifications": "Gérer mes notifications",
|
||||||
"We use your timezone to make sure you get notifications for an event at the correct time.": "Nous utilisons votre fuseau hoaire pour nous assurer que vous recevez les notifications pour un événement au bon moment.",
|
"We use your timezone to make sure you get notifications for an event at the correct time.": "Nous utilisons votre fuseau horaire pour nous assurer que vous recevez les notifications pour un événement au bon moment.",
|
||||||
"Your timezone was detected as {timezone}.": "Votre fuseau horaire a été détecté en tant que {timezone}.",
|
"Your timezone was detected as {timezone}.": "Votre fuseau horaire a été détecté en tant que {timezone}.",
|
||||||
"Manage my settings": "Gérer mes paramètres",
|
"Manage my settings": "Gérer mes paramètres",
|
||||||
"Let's define a few settings": "Définissons quelques paramètres",
|
"Let's define a few settings": "Définissons quelques paramètres",
|
||||||
@ -646,7 +646,7 @@
|
|||||||
"Participations": "Participations",
|
"Participations": "Participations",
|
||||||
"Nothing to see here": "Il n'y a rien à voir ici",
|
"Nothing to see here": "Il n'y a rien à voir ici",
|
||||||
"Not confirmed": "Non confirmé·e",
|
"Not confirmed": "Non confirmé·e",
|
||||||
"{actor} suspended profile {profile}": "{actor} a suspendu le profil {profile}",
|
"{moderator} suspended profile {profile}": "{moderator} a suspendu le profil {profile}",
|
||||||
"Suspend": "Suspendre",
|
"Suspend": "Suspendre",
|
||||||
"Unsuspend": "Annuler la suspension",
|
"Unsuspend": "Annuler la suspension",
|
||||||
"None": "Aucun",
|
"None": "Aucun",
|
||||||
@ -665,5 +665,7 @@
|
|||||||
"I agree to the {instanceRules} and {termsOfService}": "J'accepte les {instanceRules} et les {termsOfService}",
|
"I agree to the {instanceRules} and {termsOfService}": "J'accepte les {instanceRules} et les {termsOfService}",
|
||||||
"This email is already used.": "Cette adresse email est déjà utilisée.",
|
"This email is already used.": "Cette adresse email est déjà utilisée.",
|
||||||
"Powered by {mobilizon}. © 2018 - {date} The Mobilizon Contributors - Made with the financial support of {contributors}.": "Propulsé par {mobilizon}. © 2018 - {date} Les contributeur·ices Mobilizon - Fait avec le soutien financier de {contributors}.",
|
"Powered by {mobilizon}. © 2018 - {date} The Mobilizon Contributors - Made with the financial support of {contributors}.": "Propulsé par {mobilizon}. © 2018 - {date} Les contributeur·ices Mobilizon - Fait avec le soutien financier de {contributors}.",
|
||||||
"more than 1360 contributors": "plus de 1360 contributeur·ices"
|
"more than 1360 contributors": "plus de 1360 contributeur·ices",
|
||||||
|
"{moderator} has unsuspended profile {profile}": "{moderator} a annulé la suspension de {profile}",
|
||||||
|
"{moderator} has deleted user {user}": "{moderator} a supprimé l'utilisateur·ice {user}"
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ export enum ActionLogAction {
|
|||||||
COMMENT_DELETION = "COMMENT_DELETION",
|
COMMENT_DELETION = "COMMENT_DELETION",
|
||||||
ACTOR_SUSPENSION = "ACTOR_SUSPENSION",
|
ACTOR_SUSPENSION = "ACTOR_SUSPENSION",
|
||||||
ACTOR_UNSUSPENSION = "ACTOR_UNSUSPENSION",
|
ACTOR_UNSUSPENSION = "ACTOR_UNSUSPENSION",
|
||||||
|
USER_DELETION = "USER_DELETION",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IActionLog {
|
export interface IActionLog {
|
||||||
|
@ -35,7 +35,12 @@
|
|||||||
</router-link>
|
</router-link>
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
<b-table-column field="confirmedAt" :label="$t('Confirmed at')" :centered="true">
|
<b-table-column field="confirmedAt" :label="$t('Confirmed at')" :centered="true">
|
||||||
|
<template v-if="props.row.confirmedAt">
|
||||||
{{ props.row.confirmedAt | formatDateTimeString }}
|
{{ props.row.confirmedAt | formatDateTimeString }}
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
{{ $t("Not confirmed") }}
|
||||||
|
</template>
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
<b-table-column field="locale" :label="$t('Language')" :centered="true">
|
<b-table-column field="locale" :label="$t('Language')" :centered="true">
|
||||||
{{ props.row.locale }}
|
{{ props.row.locale }}
|
||||||
|
@ -92,7 +92,7 @@
|
|||||||
v-model="event.visibility"
|
v-model="event.visibility"
|
||||||
name="eventVisibility"
|
name="eventVisibility"
|
||||||
:native-value="EventVisibility.UNLISTED"
|
:native-value="EventVisibility.UNLISTED"
|
||||||
>{{ $t("Only accessible through link and search (private)") }}</b-radio
|
>{{ $t("Only accessible through link (private)") }}</b-radio
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="field">
|
<!-- <div class="field">
|
||||||
|
@ -7,10 +7,10 @@
|
|||||||
<i18n
|
<i18n
|
||||||
v-if="log.action === ActionLogAction.REPORT_UPDATE_CLOSED"
|
v-if="log.action === ActionLogAction.REPORT_UPDATE_CLOSED"
|
||||||
tag="span"
|
tag="span"
|
||||||
path="{actor} closed {report}"
|
path="{moderator} closed {report}"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
slot="actor"
|
slot="moderator"
|
||||||
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.actor.id } }"
|
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.actor.id } }"
|
||||||
>@{{ log.actor.preferredUsername }}</router-link
|
>@{{ log.actor.preferredUsername }}</router-link
|
||||||
>
|
>
|
||||||
@ -23,10 +23,10 @@
|
|||||||
<i18n
|
<i18n
|
||||||
v-else-if="log.action === ActionLogAction.REPORT_UPDATE_OPENED"
|
v-else-if="log.action === ActionLogAction.REPORT_UPDATE_OPENED"
|
||||||
tag="span"
|
tag="span"
|
||||||
path="{actor} reopened {report}"
|
path="{moderator} reopened {report}"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
slot="actor"
|
slot="moderator"
|
||||||
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.actor.id } }"
|
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.actor.id } }"
|
||||||
>@{{ log.actor.preferredUsername }}</router-link
|
>@{{ log.actor.preferredUsername }}</router-link
|
||||||
>
|
>
|
||||||
@ -39,10 +39,10 @@
|
|||||||
<i18n
|
<i18n
|
||||||
v-else-if="log.action === ActionLogAction.REPORT_UPDATE_RESOLVED"
|
v-else-if="log.action === ActionLogAction.REPORT_UPDATE_RESOLVED"
|
||||||
tag="span"
|
tag="span"
|
||||||
path="{actor} marked {report} as resolved"
|
path="{moderator} marked {report} as resolved"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
slot="actor"
|
slot="moderator"
|
||||||
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.actor.id } }"
|
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.actor.id } }"
|
||||||
>@{{ log.actor.preferredUsername }}</router-link
|
>@{{ log.actor.preferredUsername }}</router-link
|
||||||
>
|
>
|
||||||
@ -55,10 +55,10 @@
|
|||||||
<i18n
|
<i18n
|
||||||
v-else-if="log.action === ActionLogAction.NOTE_CREATION"
|
v-else-if="log.action === ActionLogAction.NOTE_CREATION"
|
||||||
tag="span"
|
tag="span"
|
||||||
path="{actor} added a note on {report}"
|
path="{moderator} added a note on {report}"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
slot="actor"
|
slot="moderator"
|
||||||
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.actor.id } }"
|
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.actor.id } }"
|
||||||
>@{{ log.actor.preferredUsername }}</router-link
|
>@{{ log.actor.preferredUsername }}</router-link
|
||||||
>
|
>
|
||||||
@ -73,10 +73,10 @@
|
|||||||
<i18n
|
<i18n
|
||||||
v-else-if="log.action === ActionLogAction.EVENT_DELETION"
|
v-else-if="log.action === ActionLogAction.EVENT_DELETION"
|
||||||
tag="span"
|
tag="span"
|
||||||
path='{actor} deleted an event named "{title}"'
|
path='{moderator} deleted an event named "{title}"'
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
slot="actor"
|
slot="moderator"
|
||||||
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.actor.id } }"
|
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.actor.id } }"
|
||||||
>@{{ log.actor.preferredUsername }}</router-link
|
>@{{ log.actor.preferredUsername }}</router-link
|
||||||
>
|
>
|
||||||
@ -85,10 +85,10 @@
|
|||||||
<i18n
|
<i18n
|
||||||
v-else-if="log.action === ActionLogAction.ACTOR_SUSPENSION"
|
v-else-if="log.action === ActionLogAction.ACTOR_SUSPENSION"
|
||||||
tag="span"
|
tag="span"
|
||||||
path="{actor} suspended profile {profile}"
|
path="{moderator} suspended profile {profile}"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link
|
||||||
slot="actor"
|
slot="moderator"
|
||||||
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.actor.id } }"
|
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.actor.id } }"
|
||||||
>@{{ log.actor.preferredUsername }}</router-link
|
>@{{ log.actor.preferredUsername }}</router-link
|
||||||
>
|
>
|
||||||
@ -98,6 +98,40 @@
|
|||||||
>{{ displayNameAndUsername(log.object) }}
|
>{{ displayNameAndUsername(log.object) }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</i18n>
|
</i18n>
|
||||||
|
<i18n
|
||||||
|
v-else-if="log.action === ActionLogAction.ACTOR_UNSUSPENSION"
|
||||||
|
tag="span"
|
||||||
|
path="{moderator} has unsuspended profile {profile}"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
slot="moderator"
|
||||||
|
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.actor.id } }"
|
||||||
|
>@{{ log.actor.preferredUsername }}</router-link
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
slot="profile"
|
||||||
|
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.object.id } }"
|
||||||
|
>{{ displayNameAndUsername(log.object) }}
|
||||||
|
</router-link>
|
||||||
|
</i18n>
|
||||||
|
<i18n
|
||||||
|
v-else-if="log.action === ActionLogAction.USER_DELETION"
|
||||||
|
tag="span"
|
||||||
|
path="{moderator} has deleted user {user}"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
slot="moderator"
|
||||||
|
:to="{ name: RouteName.ADMIN_PROFILE, params: { id: log.actor.id } }"
|
||||||
|
>@{{ log.actor.preferredUsername }}</router-link
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
v-if="log.object.confirmedAt"
|
||||||
|
slot="user"
|
||||||
|
:to="{ name: RouteName.ADMIN_USER_PROFILE, params: { id: log.object.id } }"
|
||||||
|
>{{ log.object.email }}
|
||||||
|
</router-link>
|
||||||
|
<b v-else slot="user">{{ log.object.email }}</b>
|
||||||
|
</i18n>
|
||||||
<br />
|
<br />
|
||||||
<small>{{ log.insertedAt | formatDateTimeString }}</small>
|
<small>{{ log.insertedAt | formatDateTimeString }}</small>
|
||||||
</div>
|
</div>
|
||||||
|
@ -111,6 +111,13 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp transform_action_log(User, :delete, %ActionLog{changes: changes}) do
|
||||||
|
%{
|
||||||
|
action: :user_deletion,
|
||||||
|
object: convert_changes_to_struct(User, changes)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
# Changes are stored as %{"key" => "value"} so we need to convert them back as struct
|
# Changes are stored as %{"key" => "value"} so we need to convert them back as struct
|
||||||
defp convert_changes_to_struct(struct, %{"report_id" => _report_id} = changes) do
|
defp convert_changes_to_struct(struct, %{"report_id" => _report_id} = changes) do
|
||||||
with data <- for({key, val} <- changes, into: %{}, do: {String.to_atom(key), val}),
|
with data <- for({key, val} <- changes, into: %{}, do: {String.to_atom(key), val}),
|
||||||
|
@ -110,6 +110,29 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
|||||||
{:ok, stats.participant + stats.moderator + stats.administrator + stats.creator}
|
{:ok, stats.participant + stats.moderator + stats.administrator + stats.creator}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def stats_participants(
|
||||||
|
%Event{participant_stats: %EventParticipantStats{} = stats, id: event_id} = _event,
|
||||||
|
_args,
|
||||||
|
%{context: %{current_user: %User{id: user_id} = _user}} = _resolution
|
||||||
|
) do
|
||||||
|
if Events.is_user_moderator_for_event?(user_id, event_id) do
|
||||||
|
stats =
|
||||||
|
Map.put(
|
||||||
|
stats,
|
||||||
|
:going,
|
||||||
|
stats.participant + stats.moderator + stats.administrator + stats.creator
|
||||||
|
)
|
||||||
|
|
||||||
|
{:ok, stats}
|
||||||
|
else
|
||||||
|
{:ok, %EventParticipantStats{}}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def stats_participants(_event, _args, _resolution) do
|
||||||
|
{:ok, %EventParticipantStats{}}
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
List related events
|
List related events
|
||||||
"""
|
"""
|
||||||
|
@ -5,7 +5,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
|||||||
|
|
||||||
import Mobilizon.Users.Guards
|
import Mobilizon.Users.Guards
|
||||||
|
|
||||||
alias Mobilizon.{Actors, Config, Events, Users}
|
alias Mobilizon.{Actors, Admin, Config, Events, Users}
|
||||||
alias Mobilizon.Actors.Actor
|
alias Mobilizon.Actors.Actor
|
||||||
alias Mobilizon.Crypto
|
alias Mobilizon.Crypto
|
||||||
alias Mobilizon.Federation.ActivityPub
|
alias Mobilizon.Federation.ActivityPub
|
||||||
@ -390,11 +390,20 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def delete_account(_parent, %{user_id: user_id}, %{
|
def delete_account(_parent, %{user_id: user_id}, %{
|
||||||
context: %{current_user: %User{role: role}}
|
context: %{current_user: %User{role: role} = moderator_user}
|
||||||
})
|
})
|
||||||
when is_moderator(role) do
|
when is_moderator(role) do
|
||||||
with %User{} = user <- Users.get_user(user_id) do
|
with {:moderator_actor, %Actor{} = moderator_actor} <-
|
||||||
do_delete_account(%User{} = user)
|
{:moderator_actor, Users.get_actor_for_user(moderator_user)},
|
||||||
|
%User{disabled: false} = user <- Users.get_user(user_id),
|
||||||
|
{:ok, %User{}} <- do_delete_account(%User{} = user) do
|
||||||
|
Admin.log_action(moderator_actor, "delete", user)
|
||||||
|
else
|
||||||
|
{:moderator_actor, nil} ->
|
||||||
|
{:error, "No actor found for the moderator user"}
|
||||||
|
|
||||||
|
%User{disabled: true} ->
|
||||||
|
{:error, "User already disabled"}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
|
|||||||
alias Mobilizon.Conversations.Comment
|
alias Mobilizon.Conversations.Comment
|
||||||
alias Mobilizon.Events.Event
|
alias Mobilizon.Events.Event
|
||||||
alias Mobilizon.Reports.{Note, Report}
|
alias Mobilizon.Reports.{Note, Report}
|
||||||
|
alias Mobilizon.Users.User
|
||||||
|
|
||||||
alias Mobilizon.GraphQL.Resolvers.Admin
|
alias Mobilizon.GraphQL.Resolvers.Admin
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
|
|||||||
value(:event_update)
|
value(:event_update)
|
||||||
value(:actor_suspension)
|
value(:actor_suspension)
|
||||||
value(:actor_unsuspension)
|
value(:actor_unsuspension)
|
||||||
|
value(:user_deletion)
|
||||||
end
|
end
|
||||||
|
|
||||||
@desc "The objects that can be in an action log"
|
@desc "The objects that can be in an action log"
|
||||||
@ -54,6 +56,9 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
|
|||||||
%Actor{type: "Person"}, _ ->
|
%Actor{type: "Person"}, _ ->
|
||||||
:person
|
:person
|
||||||
|
|
||||||
|
%User{}, _ ->
|
||||||
|
:user
|
||||||
|
|
||||||
_, _ ->
|
_, _ ->
|
||||||
nil
|
nil
|
||||||
end)
|
end)
|
||||||
|
@ -63,7 +63,10 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
|
|||||||
|
|
||||||
field(:draft, :boolean, description: "Whether or not the event is a draft")
|
field(:draft, :boolean, description: "Whether or not the event is a draft")
|
||||||
|
|
||||||
field(:participant_stats, :participant_stats)
|
field(:participant_stats, :participant_stats,
|
||||||
|
description: "Statistics on the event",
|
||||||
|
resolve: &Event.stats_participants/3
|
||||||
|
)
|
||||||
|
|
||||||
field(:participants, :paginated_participant_list, description: "The event's participants") do
|
field(:participants, :paginated_participant_list, description: "The event's participants") do
|
||||||
arg(:page, :integer, default_value: 1)
|
arg(:page, :integer, default_value: 1)
|
||||||
@ -121,11 +124,7 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
|
|||||||
end
|
end
|
||||||
|
|
||||||
object :participant_stats do
|
object :participant_stats do
|
||||||
field(:going, :integer,
|
field(:going, :integer, description: "The number of approved participants")
|
||||||
description: "The number of approved participants",
|
|
||||||
resolve: &Event.stats_participants_going/3
|
|
||||||
)
|
|
||||||
|
|
||||||
field(:not_approved, :integer, description: "The number of not approved participants")
|
field(:not_approved, :integer, description: "The number of not approved participants")
|
||||||
field(:not_confirmed, :integer, description: "The number of not confirmed participants")
|
field(:not_confirmed, :integer, description: "The number of not confirmed participants")
|
||||||
field(:rejected, :integer, description: "The number of rejected participants")
|
field(:rejected, :integer, description: "The number of rejected participants")
|
||||||
|
@ -15,7 +15,8 @@ defmodule Mobilizon.GraphQL.Schema.UserType do
|
|||||||
|
|
||||||
@desc "A local user of Mobilizon"
|
@desc "A local user of Mobilizon"
|
||||||
object :user do
|
object :user do
|
||||||
field(:id, non_null(:id), description: "The user's ID")
|
interfaces([:action_log_object])
|
||||||
|
field(:id, :id, description: "The user's ID")
|
||||||
field(:email, non_null(:string), description: "The user's email")
|
field(:email, non_null(:string), description: "The user's email")
|
||||||
|
|
||||||
field(:actors, non_null(list_of(:person)),
|
field(:actors, non_null(list_of(:person)),
|
||||||
|
@ -425,6 +425,16 @@ defmodule Mobilizon.Events do
|
|||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec is_user_moderator_for_event?(integer | String.t(), integer | String.t()) :: boolean
|
||||||
|
def is_user_moderator_for_event?(user_id, event_id) do
|
||||||
|
Participant
|
||||||
|
|> join(:inner, [p], a in Actor, on: p.actor_id == a.id)
|
||||||
|
|> where([p, _a], p.event_id == ^event_id)
|
||||||
|
|> where([_p, a], a.user_id == ^user_id)
|
||||||
|
|> where([p, _a], p.role == ^:creator)
|
||||||
|
|> Repo.exists?()
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Finds close events to coordinates.
|
Finds close events to coordinates.
|
||||||
Radius is in meters and defaults to 50km.
|
Radius is in meters and defaults to 50km.
|
||||||
@ -741,7 +751,8 @@ defmodule Mobilizon.Events do
|
|||||||
|> Repo.one()
|
|> Repo.one()
|
||||||
end
|
end
|
||||||
|
|
||||||
@default_participant_roles [:participant, :moderator, :administrator, :creator]
|
@moderator_roles [:moderator, :administrator, :creator]
|
||||||
|
@default_participant_roles [:participant] ++ @moderator_roles
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Returns the list of participants for an event.
|
Returns the list of participants for an event.
|
||||||
@ -810,7 +821,7 @@ defmodule Mobilizon.Events do
|
|||||||
where:
|
where:
|
||||||
p.event_id == ^event_id and
|
p.event_id == ^event_id and
|
||||||
p.actor_id ==
|
p.actor_id ==
|
||||||
^actor_id and p.role in ^[:moderator, :administrator, :creator]
|
^actor_id and p.role in ^@moderator_roles
|
||||||
)
|
)
|
||||||
) == nil)
|
) == nil)
|
||||||
end
|
end
|
||||||
|
@ -554,7 +554,8 @@ defmodule Mobilizon.GraphQL.Resolvers.ParticipantTest do
|
|||||||
|
|
||||||
test "stats_participants_for_event/3 give the number of (un)approved participants", %{
|
test "stats_participants_for_event/3 give the number of (un)approved participants", %{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
actor: actor
|
actor: actor,
|
||||||
|
user: user
|
||||||
} do
|
} do
|
||||||
event =
|
event =
|
||||||
@event
|
@event
|
||||||
@ -577,6 +578,7 @@ defmodule Mobilizon.GraphQL.Resolvers.ParticipantTest do
|
|||||||
|
|
||||||
res =
|
res =
|
||||||
conn
|
conn
|
||||||
|
|> auth_conn(user)
|
||||||
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
|
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
|
||||||
|
|
||||||
assert json_response(res, 200)["data"]["event"]["uuid"] == to_string(event.uuid)
|
assert json_response(res, 200)["data"]["event"]["uuid"] == to_string(event.uuid)
|
||||||
@ -623,12 +625,33 @@ defmodule Mobilizon.GraphQL.Resolvers.ParticipantTest do
|
|||||||
|
|
||||||
res =
|
res =
|
||||||
conn
|
conn
|
||||||
|
|> auth_conn(user)
|
||||||
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
|
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
|
||||||
|
|
||||||
assert json_response(res, 200)["data"]["event"]["uuid"] == to_string(event.uuid)
|
assert json_response(res, 200)["data"]["event"]["uuid"] == to_string(event.uuid)
|
||||||
assert json_response(res, 200)["data"]["event"]["participantStats"]["going"] == 2
|
assert json_response(res, 200)["data"]["event"]["participantStats"]["going"] == 2
|
||||||
assert json_response(res, 200)["data"]["event"]["participantStats"]["notApproved"] == 1
|
assert json_response(res, 200)["data"]["event"]["participantStats"]["notApproved"] == 1
|
||||||
assert json_response(res, 200)["data"]["event"]["participantStats"]["rejected"] == 1
|
assert json_response(res, 200)["data"]["event"]["participantStats"]["rejected"] == 1
|
||||||
|
|
||||||
|
query = """
|
||||||
|
{
|
||||||
|
event(uuid: "#{event.uuid}") {
|
||||||
|
uuid,
|
||||||
|
participantStats {
|
||||||
|
going,
|
||||||
|
notApproved,
|
||||||
|
rejected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
res =
|
||||||
|
conn
|
||||||
|
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
|
||||||
|
|
||||||
|
assert is_nil(json_response(res, 200)["errors"])
|
||||||
|
assert json_response(res, 200)["data"]["event"]["going"] == nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user