mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-23 20:54:48 -04:00
160 lines
5.2 KiB
Vue
160 lines
5.2 KiB
Vue
<script setup lang="ts">
|
||
import { useNuxtApp, useFetch } from 'nuxt/app';
|
||
|
||
import useConfig from '~/composables/useConfig.ts';
|
||
import useSimpleHead from '~/composables/useSimpleHead.ts';
|
||
|
||
definePageMeta({
|
||
path: '/admin/abuse-reports',
|
||
});
|
||
|
||
const { $translator: translator } = useNuxtApp();
|
||
useSimpleHead({
|
||
title: `${translator.translate('admin.header')} • Abuse reports`,
|
||
}, translator);
|
||
|
||
const { data: abuseReports } = await useFetch<any[]>('/api/admin/reports', { lazy: true, default: () => [] });
|
||
|
||
const config = useConfig();
|
||
|
||
const filterAutomatic = ref();
|
||
const filterKeyword = ref();
|
||
const filterIsHandled = ref(false);
|
||
const filterLocale = ref(config.locale);
|
||
|
||
const keywords = computed(() => {
|
||
const keywords = new Set();
|
||
|
||
for (const report of abuseReports.value) {
|
||
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();
|
||
});
|
||
|
||
const abuseReportsActiveCount = computed(() => {
|
||
return abuseReports.value ? abuseReports.value.filter((r) => !r.isHandled).length : '–';
|
||
});
|
||
|
||
const filteredAbuseReports = computed(() => {
|
||
if (abuseReports.value === undefined) {
|
||
return undefined;
|
||
}
|
||
|
||
return abuseReports.value.filter((r) => {
|
||
if (filterAutomatic.value === true && r.isAutomatic !== 1) {
|
||
return false;
|
||
}
|
||
if (filterAutomatic.value === false && r.isAutomatic !== 0) {
|
||
return false;
|
||
}
|
||
|
||
if (filterKeyword.value && r.comment) {
|
||
let found = false;
|
||
for (const keyword of r.comment.split(', ')) {
|
||
if (keyword.startsWith(`${filterKeyword.value} (`)) {
|
||
found = true;
|
||
}
|
||
}
|
||
if (!found) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
if (filterIsHandled.value === true && r.isHandled !== 1) {
|
||
return false;
|
||
}
|
||
if (filterIsHandled.value === false && r.isHandled !== 0) {
|
||
return false;
|
||
}
|
||
|
||
if (filterLocale.value && r.profiles && !r.profiles.split(',').includes(filterLocale.value)) {
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
});
|
||
});
|
||
</script>
|
||
|
||
<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.fullName }}
|
||
</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>
|