-
@@ -31,7 +37,7 @@
-
+
{{
t("Reported by someone on {domain}", {
domain: report.reporter.domain,
@@ -40,19 +46,22 @@
{{ t("Reported by someone anonymously") }}
-
+
{{
t("Reported by {reporter}", {
reporter: usernameWithDomain(report.reporter),
})
}}
+
+ {{ t("Reported by an unknown actor") }}
+
diff --git a/js/src/composition/apollo/report.ts b/js/src/composition/apollo/report.ts
index 37ecaece6..adfdf8a48 100644
--- a/js/src/composition/apollo/report.ts
+++ b/js/src/composition/apollo/report.ts
@@ -5,7 +5,7 @@ export function useCreateReport() {
return useMutation<
{ createReport: { id: string } },
{
- eventId?: string;
+ eventsIds?: string[];
reportedId: string;
content?: string;
commentsIds?: string[];
diff --git a/js/src/graphql/report.ts b/js/src/graphql/report.ts
index 0c4c0c3b6..9185c7f79 100644
--- a/js/src/graphql/report.ts
+++ b/js/src/graphql/report.ts
@@ -20,7 +20,7 @@ export const REPORTS = gql`
...ActorFragment
suspended
}
- event {
+ events {
id
uuid
title
@@ -42,11 +42,19 @@ const REPORT_FRAGMENT = gql`
id
reported {
...ActorFragment
+ suspended
+ ... on Person {
+ user {
+ id
+ disabled
+ }
+ }
}
reporter {
...ActorFragment
+ suspended
}
- event {
+ events {
id
uuid
title
@@ -69,6 +77,14 @@ const REPORT_FRAGMENT = gql`
actor {
...ActorFragment
}
+ updatedAt
+ deletedAt
+ uuid
+ event {
+ id
+ uuid
+ title
+ }
}
notes {
id
@@ -97,14 +113,14 @@ export const REPORT = gql`
export const CREATE_REPORT = gql`
mutation CreateReport(
- $eventId: ID
+ $eventsIds: [ID]
$reportedId: ID!
$content: String
$commentsIds: [ID]
$forward: Boolean
) {
createReport(
- eventId: $eventId
+ eventsIds: $eventsIds
reportedId: $reportedId
content: $content
commentsIds: $commentsIds
diff --git a/js/src/i18n/en_US.json b/js/src/i18n/en_US.json
index 58d487f1f..fa50e35d2 100644
--- a/js/src/i18n/en_US.json
+++ b/js/src/i18n/en_US.json
@@ -78,8 +78,6 @@
"Date parameters": "Date parameters",
"Date": "Date",
"Default": "Default",
- "Delete Comment": "Delete Comment",
- "Delete Event": "Delete Event",
"Delete account": "Delete account",
"Delete event": "Delete event",
"Delete everything": "Delete everything",
@@ -1582,5 +1580,30 @@
"This application will be allowed to list your suggested group events": "This application will be allowed to list your suggested group events",
"{profile} joined the the event {event}.": "{profile} joined the the event {event}.",
"You joined the event {event}.": "You joined the event {event}.",
- "An anonymous profile joined the event {event}.": "An anonymous profile joined the event {event}."
+ "An anonymous profile joined the event {event}.": "An anonymous profile joined the event {event}.",
+ "Delete event and resolve report": "Delete event and resolve report",
+ "No content found": "No content found",
+ "Maybe the content was removed by the author or a moderator": "Maybe the content was removed by the author or a moderator",
+ "This will also resolve the report.": "This will also resolve the report.",
+ "Are you sure you want to
delete this event?
This action cannot be undone. You may want to engage the discussion with the event creator and ask them to edit their event instead.": "Are you sure you want to
delete this event?
This action cannot be undone. You may want to engage the discussion with the event creator and ask them to edit their event instead.",
+ "Are you sure you want to
delete this comment?
This action cannot be undone.": "Are you sure you want to
delete this comment?
This action cannot be undone.",
+ "Delete comment and resolve report": "Delete comment and resolve report",
+ "Delete comment": "Delete comment",
+ "Event deleted and report resolved": "Event deleted and report resolved",
+ "Event deleted": "Event deleted",
+ "Comment deleted and report resolved": "Comment deleted and report resolved",
+ "Comment under event {eventTitle}": "Comment under event {eventTitle}",
+ "Do you really want to suspend this profile? All of the profiles content will be deleted.": "Do you really want to suspend this profile? All of the profiles content will be deleted.",
+ "There will be no way to restore the profile's data!": "There will be no way to restore the profile's data!",
+ "Suspend the profile": "Suspend the profile",
+ "The following user's profiles will be deleted, with all their data:": "The following user's profiles will be deleted, with all their data:",
+ "Do you really want to suspend the account « {emailAccount} » ?": "Do you really want to suspend the account « {emailAccount} » ?",
+ "There will be no way to restore the user's data!": "There will be no way to restore the user's data!",
+ "User suspended and report resolved": "User suspended and report resolved",
+ "Profile suspended and report resolved": "Profile suspended and report resolved",
+ "{profileName} (suspended)": "{profileName} (suspended)",
+ "Reported by an unknown actor": "Reported by an unknown actor",
+ "Reported at": "Reported at",
+ "Updated at": "Updated at",
+ "Suspend the profile?": "Suspend the profile?"
}
\ No newline at end of file
diff --git a/js/src/i18n/fr_FR.json b/js/src/i18n/fr_FR.json
index 32fee266e..8fc9568aa 100644
--- a/js/src/i18n/fr_FR.json
+++ b/js/src/i18n/fr_FR.json
@@ -1578,5 +1578,30 @@
"This application will be allowed to list your suggested group events": "Cetta application sera autorisée à lister les événements de vos groupes qui vous sont suggérés",
"{profile} joined the the event {event}.": "{profile} a rejoint l'événement {event}.",
"You joined the event {event}.": "Vous avez rejoint l'événement {event}.",
- "An anonymous profile joined the event {event}.": "Un profil anonyme a rejoint l'événement {event}."
+ "An anonymous profile joined the event {event}.": "Un profil anonyme a rejoint l'événement {event}.",
+ "Delete event and resolve report": "Supprimer l'événement et résoudre le signalement",
+ "No content found": "Aucun contenu trouvé",
+ "Maybe the content was removed by the author or a moderator": "Peut-être que le contenu a été supprimé par l'auteur·ice ou un·e modérateur·ice",
+ "This will also resolve the report.": "Cela résoudra également le signalement.",
+ "Are you sure you want to
delete this event?
This action cannot be undone. You may want to engage the discussion with the event creator and ask them to edit their event instead.": "Êtes-vous certain⋅e de vouloir
supprimer cet événement ? Cette action n'est pas réversible. Vous voulez peut-être engager la discussion avec le créateur de l'événement et lui demander de modifier son événement à la place.",
+ "Are you sure you want to
delete this comment?
This action cannot be undone.": "Êtes-vous certain⋅e de vouloir
supprimer ce commentaire ?
Cette action ne peut pas être annulée.",
+ "Delete comment and resolve report": "Supprimer le commentaire et résoudre le signalement",
+ "Delete comment": "Supprimer le commentaire",
+ "Event deleted and report resolved": "Événement supprimé et signalement résolu",
+ "Event deleted": "Événement supprimé",
+ "Comment deleted and report resolved": "Commentaire supprimé et signalement résolu",
+ "Comment under event {eventTitle}": "Commentaire sous l'événement {eventTitle}",
+ "Suspend the profile?": "Suspendre le profil ?",
+ "Do you really want to suspend this profile? All of the profiles content will be deleted.": "Voulez-vous vraiment suspendre ce profil ? Tout le contenu du profil sera supprimé.",
+ "There will be no way to restore the profile's data!": "Il n'y aura aucun moyen de restorer les données du profil !",
+ "Suspend the profile": "Suspendre le profil",
+ "The following user's profiles will be deleted, with all their data:": "Les profils suivants de l'utilisateur·ice seront supprimés, avec toutes leurs données :",
+ "Do you really want to suspend the account « {emailAccount} » ?": "Voulez-vous vraiment suspendre le compte « {emailAccount} » ?",
+ "There will be no way to restore the user's data!": "Il n'y aura aucun moyen de restorer les données de l'utilisateur·ice !",
+ "User suspended and report resolved": "Utilisateur suspendu et signalement résolu",
+ "Profile suspended and report resolved": "Profil suspendu et signalement résolu",
+ "{profileName} (suspended)": "{profileName} (suspendu·e)",
+ "Reported by an unknown actor": "Signalé par un·e acteur·ice inconnu·e",
+ "Reported at": "Signalé à",
+ "Updated at": "Mis à jour à"
}
diff --git a/js/src/types/report.model.ts b/js/src/types/report.model.ts
index dd54158a3..dc00599a3 100644
--- a/js/src/types/report.model.ts
+++ b/js/src/types/report.model.ts
@@ -14,9 +14,9 @@ export interface IReportNote extends IActionLogObject {
}
export interface IReport extends IActionLogObject {
id: string;
- reported: IActor;
+ reported: IActor | undefined;
reporter: IPerson;
- event?: IEvent;
+ events?: IEvent[];
comments: IComment[];
content: string;
notes: IReportNote[];
diff --git a/js/src/views/Moderation/ReportView.vue b/js/src/views/Moderation/ReportView.vue
index 221d88824..40177b3b9 100644
--- a/js/src/views/Moderation/ReportView.vue
+++ b/js/src/views/Moderation/ReportView.vue
@@ -65,7 +65,7 @@
-
+
{{ t("Reported group") }} |
|
-
+
{{ t("Reported identity") }}
|
-
+ |
- {{ displayNameAndUsername(report.reported) }}
+
+
+
+ {{ displayNameAndUsername(report.reported) }}
+
+
+
+ {{
+ displayNameAndUsername(report.reported)
+ }}
+ {{ t("Suspend the profile") }}
+ {{ t("Suspend the account") }}
+ |
+
+
+
+ {{ t("Reported identity") }}
+ |
+
+ {{ t("Unknown actor") }}
|
{{ t("Reported by") }} |
-
+ |
{{ report.reporter.domain }}
|
-
+ |
{{ displayNameAndUsername(report.reporter) }}
|
+
+ {{ t("Unknown actor") }}
+ |
- {{ t("Reported") }} |
+ {{ t("Reported at") }} |
{{ formatDateTimeString(report.insertedAt) }} |
- {{ t("Updated") }} |
+ {{ t("Updated at") }} |
{{ formatDateTimeString(report.updatedAt) }} |
@@ -150,26 +190,6 @@
{{ t("Unknown") }}
-
- {{ t("Event") }} |
-
-
- {{ report.event.title }}
-
- {{ t("Delete") }}
- |
-
@@ -178,7 +198,7 @@
{{ t("Report reason") }}
-
+
-
-
+
+
{{ report.reported.name }}
@{{ usernameWithDomain(report.reported) }}
+
{{ t("Unknown actor") }}
{{ t("Reported content") }}
-
-
{{ t("Delete") }}
+
+ -
+
+ {{
+ t("Delete event and resolve report")
+ }}{{ t("Delete event") }}
+
+
{{ t("Reported content") }}
-
-
-
-
-
-
-
-
-
-
-
{{ comment.actor.name }}
-
@{{ comment.actor.preferredUsername }}
-
-
{{ t("Unknown actor") }}
-
-
-
- {{ t("Delete") }}
+
+
-
-
+ {{ comment.event?.title }}
+
+
+
+
+ {{
+ t("Delete comment and resolve report")
+ }}{{ t("Delete comment") }}
+
+
+ {{ t("No content found") }}
+
+ {{ t("Maybe the content was removed by the author or a moderator") }}
+
+
+
+
{{ t("Notes") }}
import { CREATE_REPORT_NOTE, REPORT, UPDATE_REPORT } from "@/graphql/report";
import { IReport, IReportNote } from "@/types/report.model";
-import { displayNameAndUsername, usernameWithDomain } from "@/types/actor";
+import {
+ IPerson,
+ displayNameAndUsername,
+ usernameWithDomain,
+} from "@/types/actor";
import { DELETE_EVENT } from "@/graphql/event";
import uniq from "lodash/uniq";
import { nl2br } from "@/utils/html";
@@ -325,7 +374,7 @@ import { ActorType, AntiSpamFeedback, ReportStatusEnum } from "@/types/enums";
import RouteName from "@/router/name";
import { GraphQLError } from "graphql";
import { ApolloCache, FetchResult } from "@apollo/client/core";
-import { useMutation, useQuery } from "@vue/apollo-composable";
+import { useLazyQuery, useMutation, useQuery } from "@vue/apollo-composable";
import { useCurrentActorClient } from "@/composition/apollo/actor";
import { useHead } from "@vueuse/head";
import { useI18n } from "vue-i18n";
@@ -337,6 +386,13 @@ import { Dialog } from "@/plugins/dialog";
import { Notifier } from "@/plugins/notifier";
import EventCard from "@/components/Event/EventCard.vue";
import { useFeatures } from "@/composition/apollo/config";
+import { IEvent } from "@/types/event.model";
+import EmptyContent from "@/components/Utils/EmptyContent.vue";
+import EventComment from "@/components/Comment/EventComment.vue";
+import { SUSPEND_PROFILE } from "@/graphql/actor";
+import { GET_USER, SUSPEND_USER } from "@/graphql/user";
+import { IUser } from "@/types/current-user.model";
+import { waitApolloQuery } from "@/vue-apollo";
const router = useRouter();
@@ -374,6 +430,14 @@ const errors = ref
([]);
const noteContent = ref("");
+const reportedContent = computed(() => {
+ return [...(report.value?.events ?? []), ...(report.value?.comments ?? [])];
+});
+
+const isOnlyReportedContent = computed(
+ () => reportedContent.value.length === 1
+);
+
const {
mutate: createReportNoteMutation,
onDone: createReportNoteMutationDone,
@@ -419,26 +483,39 @@ createReportNoteMutationError((error) => {
const dialog = inject