PronounsPage/pages/admin/abuseReports.vue
2024-09-12 10:11:25 +02:00

168 lines
5.7 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<Page>
<NotFound v-if="!$isGranted('users') && !$isGranted('community')" />
<div v-else>
<p>
<nuxt-link to="/admin">
<Icon v="user-cog" />
<T>admin.header</T>
</nuxt-link>
</p>
<h2>
<Icon v="siren-on" />
Abuse reports
({{ abuseReportsActiveCount }})
</h2>
<form class="row mt-3">
<div class="col">
<select v-model="filterAutomatic" class="form-select">
<option :value="undefined">
All report types
</option>
<option :value="true">
Only automatic keywords
</option>
<option :value="false">
Only user reports
</option>
</select>
</div>
<div class="col">
<select v-model="filterKeyword" class="form-select">
<option :value="undefined">
All automatic keywords
</option>
<option v-for="keyword in keywords" :value="keyword">
{{ keyword }}
</option>
</select>
</div>
<div class="col">
<select v-model="filterLocale" class="form-select">
<option :value="undefined">
All language versions
</option>
<option v-for="locale in $locales" :value="locale.code">
{{ locale.name }}
</option>
</select>
</div>
<div class="col">
<select v-model="filterIsHandled" class="form-select">
<option :value="undefined">
All report statuses
</option>
<option :value="true">
Only handled reports
</option>
<option :value="false">
Only open reports
</option>
</select>
</div>
</form>
<section>
<ModerationRules type="rulesUsers" emphasise />
<ModerationRules type="susRegexes" label="Keywords for automated triggers" />
<Loading :value="filteredAbuseReports">
<AbuseReports :abuse-reports="filteredAbuseReports" allow-resolving allow-queue />
</Loading>
</section>
</div>
</Page>
</template>
<script>
import { useNuxtApp, useFetch } from 'nuxt/app';
import useConfig from '~/composables/useConfig.ts';
import useSimpleHead from '~/composables/useSimpleHead.ts';
export default {
async setup() {
definePageMeta({
path: '/admin/abuse-reports',
});
const { $translator: translator } = useNuxtApp();
useSimpleHead({
title: `${translator.translate('admin.header')} • Abuse reports`,
}, translator);
const { data: abuseReports } = await useFetch('/api/admin/reports', { lazy: true });
return {
config: useConfig(),
abuseReports,
};
},
data() {
return {
filterAutomatic: undefined,
filterKeyword: undefined,
filterIsHandled: false,
filterLocale: this.config.locale,
};
},
computed: {
keywords() {
const keywords = new Set();
for (const report of this.abuseReports) {
if (!report.isAutomatic || report.comment.indexOf(' (') < 0) {
continue;
}
for (const keyword of report.comment.split(', ')) {
keywords.add(keyword.substring(0, keyword.indexOf(' (')));
}
}
return [...keywords].sort();
},
abuseReportsActiveCount() {
return this.abuseReports ? this.abuseReports.filter((r) => !r.isHandled).length : '';
},
filteredAbuseReports() {
if (this.abuseReports === undefined) {
return undefined;
}
return this.abuseReports.filter((r) => {
if (this.filterAutomatic === true && r.isAutomatic !== 1) {
return false;
}
if (this.filterAutomatic === false && r.isAutomatic !== 0) {
return false;
}
if (this.filterKeyword && r.comment) {
let found = false;
for (const keyword of r.comment.split(', ')) {
if (keyword.startsWith(`${this.filterKeyword} (`)) {
found = true;
}
}
if (!found) {
return false;
}
}
if (this.filterIsHandled === true && r.isHandled !== 1) {
return false;
}
if (this.filterIsHandled === false && r.isHandled !== 0) {
return false;
}
if (this.filterLocale && r.profiles && !r.profiles.split(',').includes(this.filterLocale)) {
return false;
}
return true;
});
},
},
};
</script>