Skip to content

Commit 85137c3

Browse files
authored
Add a type filter to the modlogs (#1714)
1 parent 5e6d684 commit 85137c3

File tree

19 files changed

+290
-127
lines changed

19 files changed

+290
-127
lines changed

assets/styles/app.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
@use 'pages/post_single';
5252
@use 'pages/post_front';
5353
@use 'pages/page_bookmarks';
54+
@use 'pages/page_modlog';
5455
@use 'themes/kbin';
5556
@use 'themes/default';
5657
@use 'themes/solarized';

assets/styles/layout/_layout.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,10 @@ figure {
370370
gap: .25rem;
371371
}
372372

373+
.flex-item {
374+
flex-grow: 1;
375+
}
376+
373377
@include b.media-breakpoint-down(lg) {
374378
.flex.mobile {
375379
display: block;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.page-modlog {
2+
.ts-wrapper .ts-control input {
3+
min-width: unset;
4+
}
5+
6+
.ts-wrapper {
7+
margin-bottom: 0;
8+
}
9+
}

config/mbin_routes/magazine.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ magazine_moderators:
4040
methods: [GET]
4141

4242
magazine_modlog:
43-
controller: App\Controller\Magazine\MagazineLogController
43+
controller: App\Controller\ModlogController::magazine
4444
path: /m/{name}/modlog
4545
methods: [GET]
4646

config/mbin_routes/modlog.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
modlog:
2-
controller: App\Controller\ModlogController
2+
controller: App\Controller\ModlogController::instance
33
path: /modlog
44
methods: [ GET ]

src/Controller/Api/Instance/InstanceModLogApi.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
namespace App\Controller\Api\Instance;
66

77
use App\DTO\MagazineLogResponseDto;
8+
use App\Entity\MagazineLog;
89
use App\Repository\MagazineLogRepository;
910
use App\Schema\PaginationSchema;
1011
use Nelmio\ApiDocBundle\Attribute\Model;
1112
use OpenApi\Attributes as OA;
1213
use Symfony\Component\HttpFoundation\JsonResponse;
14+
use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;
1315
use Symfony\Component\RateLimiter\RateLimiterFactory;
1416

1517
class InstanceModLogApi extends InstanceBaseApi
@@ -64,6 +66,12 @@ class InstanceModLogApi extends InstanceBaseApi
6466
in: 'query',
6567
schema: new OA\Schema(type: 'integer', default: MagazineLogRepository::PER_PAGE, minimum: self::MIN_PER_PAGE, maximum: self::MAX_PER_PAGE)
6668
)]
69+
#[OA\Parameter(
70+
name: 'types[]',
71+
description: 'The types of magazine logs to retrieve',
72+
in: 'query',
73+
schema: new OA\Schema(type: 'array', items: new OA\Items(type: 'string', enum: MagazineLog::CHOICES))
74+
)]
6775
#[OA\Tag('instance')]
6876
/**
6977
* Retrieve information about moderation actions taken across the instance.
@@ -72,18 +80,20 @@ public function collection(
7280
MagazineLogRepository $repository,
7381
RateLimiterFactory $apiReadLimiter,
7482
RateLimiterFactory $anonymousApiReadLimiter,
83+
#[MapQueryParameter] ?array $types = null,
7584
): JsonResponse {
7685
$headers = $this->rateLimit($apiReadLimiter, $anonymousApiReadLimiter);
7786

7887
$request = $this->request->getCurrentRequest();
79-
$logs = $repository->listAll(
88+
$logs = $repository->findByCustom(
8089
$this->getPageNb($request),
81-
self::constrainPerPage($request->get('perPage', MagazineLogRepository::PER_PAGE))
90+
self::constrainPerPage($request->get('perPage', MagazineLogRepository::PER_PAGE)),
91+
types: $types,
8292
);
8393

8494
$dtos = [];
8595
foreach ($logs->getCurrentPageResults() as $value) {
86-
array_push($dtos, $this->serializeLogItem($value));
96+
$dtos[] = $this->serializeLogItem($value);
8797
}
8898

8999
return new JsonResponse(

src/Controller/Api/Magazine/MagazineModLogApi.php

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66

77
use App\DTO\MagazineLogResponseDto;
88
use App\Entity\Magazine;
9+
use App\Entity\MagazineLog;
910
use App\Repository\MagazineLogRepository;
10-
use App\Repository\MagazineRepository;
1111
use App\Schema\PaginationSchema;
1212
use Nelmio\ApiDocBundle\Attribute\Model;
1313
use OpenApi\Attributes as OA;
1414
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
1515
use Symfony\Component\HttpFoundation\JsonResponse;
16+
use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;
1617
use Symfony\Component\RateLimiter\RateLimiterFactory;
1718

1819
class MagazineModLogApi extends MagazineBaseApi
@@ -78,29 +79,37 @@ class MagazineModLogApi extends MagazineBaseApi
7879
in: 'query',
7980
schema: new OA\Schema(type: 'integer', default: MagazineLogRepository::PER_PAGE, minimum: self::MIN_PER_PAGE, maximum: self::MAX_PER_PAGE)
8081
)]
82+
#[OA\Parameter(
83+
name: 'types[]',
84+
description: 'The types of magazine logs to retrieve',
85+
in: 'query',
86+
schema: new OA\Schema(type: 'array', items: new OA\Items(type: 'string', enum: MagazineLog::CHOICES))
87+
)]
8188
#[OA\Tag('magazine')]
8289
/**
8390
* Retrieve information about moderation actions taken in the magazine.
8491
*/
8592
public function collection(
8693
#[MapEntity(id: 'magazine_id')]
8794
Magazine $magazine,
88-
MagazineRepository $repository,
95+
MagazineLogRepository $repository,
8996
RateLimiterFactory $apiReadLimiter,
9097
RateLimiterFactory $anonymousApiReadLimiter,
98+
#[MapQueryParameter] ?array $types = null,
9199
): JsonResponse {
92100
$headers = $this->rateLimit($apiReadLimiter, $anonymousApiReadLimiter);
93101

94102
$request = $this->request->getCurrentRequest();
95-
$logs = $repository->findModlog(
96-
$magazine,
103+
$logs = $repository->findByCustom(
97104
$this->getPageNb($request),
98-
self::constrainPerPage($request->get('perPage', MagazineLogRepository::PER_PAGE))
105+
self::constrainPerPage($request->get('perPage', MagazineLogRepository::PER_PAGE)),
106+
types: $types,
107+
magazine: $magazine,
99108
);
100109

101110
$dtos = [];
102111
foreach ($logs->getCurrentPageResults() as $value) {
103-
array_push($dtos, $this->serializeLogItem($value));
112+
$dtos[] = $this->serializeLogItem($value);
104113
}
105114

106115
return new JsonResponse(

src/Controller/Magazine/MagazineLogController.php

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/Controller/ModlogController.php

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,73 @@
44

55
namespace App\Controller;
66

7+
use App\DTO\ModlogFilterDto;
8+
use App\Entity\Magazine;
9+
use App\Form\ModlogFilterType;
710
use App\Repository\MagazineLogRepository;
11+
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
812
use Symfony\Component\HttpFoundation\Request;
913
use Symfony\Component\HttpFoundation\Response;
1014

1115
class ModlogController extends AbstractController
1216
{
13-
public function __invoke(MagazineLogRepository $repository, Request $request): Response
17+
public function __construct(
18+
private readonly MagazineLogRepository $magazineLogRepository,
19+
) {
20+
}
21+
22+
public function instance(Request $request): Response
1423
{
24+
$dto = new ModlogFilterDto();
25+
$dto->magazine = null;
26+
$form = $this->createForm(ModlogFilterType::class, $dto, ['method' => 'GET']);
27+
$form->handleRequest($request);
28+
if ($form->isSubmitted() && $form->isValid()) {
29+
/** @var ModlogFilterDto $dto */
30+
$dto = $form->getData();
31+
32+
if (null !== $dto->magazine) {
33+
return $this->redirectToRoute('magazine_modlog', ['name' => $dto->magazine->name]);
34+
}
35+
$logs = $this->magazineLogRepository->findByCustom($this->getPageNb($request), types: $dto->types);
36+
} else {
37+
$logs = $this->magazineLogRepository->findByCustom($this->getPageNb($request));
38+
}
39+
40+
return $this->render(
41+
'modlog/front.html.twig',
42+
[
43+
'logs' => $logs,
44+
'form' => $form,
45+
]
46+
);
47+
}
48+
49+
public function magazine(#[MapEntity] ?Magazine $magazine, Request $request): Response
50+
{
51+
$dto = new ModlogFilterDto();
52+
$dto->magazine = $magazine;
53+
$form = $this->createForm(ModlogFilterType::class, $dto, ['method' => 'GET']);
54+
$form->handleRequest($request);
55+
if ($form->isSubmitted() && $form->isValid()) {
56+
/** @var ModlogFilterDto $dto */
57+
$dto = $form->getData();
58+
if (null === $dto->magazine) {
59+
return $this->redirectToRoute('modlog');
60+
} elseif ($dto->magazine?->name !== $magazine->name) {
61+
return $this->redirectToRoute('magazine_modlog', ['name' => $dto->magazine->name]);
62+
}
63+
$logs = $this->magazineLogRepository->findByCustom($this->getPageNb($request), types: $dto->types, magazine: $magazine);
64+
} else {
65+
$logs = $this->magazineLogRepository->findByCustom($this->getPageNb($request), magazine: $magazine);
66+
}
67+
1568
return $this->render(
1669
'modlog/front.html.twig',
1770
[
18-
'logs' => $repository->listAll($this->getPageNb($request)),
71+
'magazine' => $magazine,
72+
'logs' => $logs,
73+
'form' => $form,
1974
]
2075
);
2176
}

src/DTO/ModlogFilterDto.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\DTO;
6+
7+
use App\Entity\Magazine;
8+
9+
class ModlogFilterDto
10+
{
11+
/**
12+
* @var string[]
13+
*/
14+
public array $types;
15+
16+
public ?Magazine $magazine;
17+
}

0 commit comments

Comments
 (0)