Skip to content

Commit da94e07

Browse files
committed
feat: add server.type filter and sort to Installation, Site, Domain
Adds a "Server type" dropdown filter (Prod / Stg / DevOps / GPU via ServerTypeType::CHOICES) and makes the Type column header clickable to sort on those three admin lists. ServerTypeFilter learned to handle dotted property names by joining the relation itself — EasyAdmin doesn't auto-join for filters on nested paths (EasyCorp/EasyAdminBundle#4120). The filter reuses the plain relation name as the join alias to match EA's own sort-side auto-join, so combining filter + sort on the same association produces a single JOIN in the generated SQL.
1 parent 25ab300 commit da94e07

4 files changed

Lines changed: 37 additions & 6 deletions

File tree

src/Controller/Admin/DomainCrudController.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use App\Admin\Field\ServerTypeField;
99
use App\Admin\Field\SiteTypeField;
1010
use App\Entity\Domain;
11+
use App\Form\Type\Admin\ServerTypeFilter;
1112
use App\Trait\ExportCrudControllerTrait;
1213
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
1314
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
@@ -52,7 +53,7 @@ public function configureFields(string $pageName): iterable
5253
yield DomainField::new('address')->setColumns(12);
5354
yield SiteTypeField::new('site.type')->hideOnIndex();
5455
yield AssociationField::new('site')->hideOnIndex();
55-
yield ServerTypeField::new('server.type')->setLabel('Type');
56+
yield ServerTypeField::new('server.type')->setLabel('Type')->setSortable(true);
5657
yield AssociationField::new('server');
5758
yield AssociationField::new('detectionResult')->hideOnIndex();
5859
yield DateTimeField::new('createdAt')->hideOnIndex();
@@ -66,6 +67,7 @@ public function configureFilters(Filters $filters): Filters
6667
->add('address')
6768
->add('site')
6869
->add('server')
70+
->add(ServerTypeFilter::new('server.type', 'Server type'))
6971
;
7072
}
7173
}

src/Controller/Admin/InstallationCrudController.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use App\Entity\Installation;
1313
use App\Form\Type\Admin\FrameworkFilter;
1414
use App\Form\Type\Admin\SemverFilter;
15+
use App\Form\Type\Admin\ServerTypeFilter;
1516
use App\Trait\ExportCrudControllerTrait;
1617
use App\Trait\SemverSortableCrudControllerTrait;
1718
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
@@ -68,7 +69,7 @@ public function configureFields(string $pageName): iterable
6869
yield CodeEditorField::new('gitChanges')->hideOnIndex();
6970
yield AssociationField::new('sites')->hideOnIndex();
7071
yield RootDirField::new('rootDir')->setColumns(12);
71-
yield ServerTypeField::new('server.type')->setLabel('Type');
72+
yield ServerTypeField::new('server.type')->setLabel('Type')->setSortable(true);
7273
yield AssociationField::new('server');
7374
yield AssociationField::new('detectionResult')->hideOnIndex();
7475
yield DateTimeField::new('createdAt')->hideOnIndex();
@@ -86,6 +87,7 @@ public function configureFilters(Filters $filters): Filters
8687
->add(SemverFilter::new('composerVersion', 'Comp.'))
8788
->add('rootDir')
8889
->add('server')
90+
->add(ServerTypeFilter::new('server.type', 'Server type'))
8991
// ->add(SystemFilter::new('system')->mapped(false))
9092
;
9193
}

src/Controller/Admin/SiteCrudController.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use App\Admin\Field\VersionField;
1414
use App\Entity\Site;
1515
use App\Form\Type\Admin\SemverFilter;
16+
use App\Form\Type\Admin\ServerTypeFilter;
1617
use App\Trait\ExportCrudControllerTrait;
1718
use App\Trait\SemverSortableCrudControllerTrait;
1819
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
@@ -67,7 +68,7 @@ public function configureFields(string $pageName): iterable
6768
yield RootDirField::new('rootDir')->setColumns(12)->hideOnIndex();
6869
yield VersionField::new('phpVersion')->setLabel('PHP');
6970
yield AssociationField::new('installation')->hideOnIndex();
70-
yield ServerTypeField::new('server.type')->setLabel('Type');
71+
yield ServerTypeField::new('server.type')->setLabel('Type')->setSortable(true);
7172
yield AssociationField::new('server');
7273
yield AssociationField::new('detectionResult')->hideOnIndex();
7374
yield DateTimeField::new('createdAt')->hideOnIndex();
@@ -80,7 +81,8 @@ public function configureFilters(Filters $filters): Filters
8081
->add('primaryDomain')
8182
->add('configFilePath')
8283
->add(SemverFilter::new('phpVersion', 'PHP'))
83-
->add('server');
84+
->add('server')
85+
->add(ServerTypeFilter::new('server.type', 'Server type'));
8486
}
8587

8688
#[\Override]

src/Form/Type/Admin/ServerTypeFilter.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,32 @@ public static function new(string $propertyName, false|string|TranslatableInterf
2727

2828
public function apply(QueryBuilder $queryBuilder, FilterDataDto $filterDataDto, ?FieldDto $fieldDto, EntityDto $entityDto): void
2929
{
30-
$queryBuilder->andWhere(sprintf('%s.%s = :type', $filterDataDto->getEntityAlias(), $filterDataDto->getProperty()))
31-
->setParameter('type', $filterDataDto->getValue());
30+
$rootAlias = $filterDataDto->getEntityAlias();
31+
$property = $filterDataDto->getProperty();
32+
$parameter = $filterDataDto->getParameterName();
33+
$value = $filterDataDto->getValue();
34+
35+
// EasyAdmin doesn't auto-join nested-property filters; if the
36+
// property crosses a relation (e.g. "server.type"), join it
37+
// ourselves and reference the joined alias. We reuse the plain
38+
// relation name as the join alias to match EA's own sort-side
39+
// auto-join (see EntityRepository::addOrderClause), so combining
40+
// sort + filter on the same association produces a single JOIN.
41+
// Background: https://github.com/EasyCorp/EasyAdminBundle/issues/4120.
42+
if (str_contains($property, '.')) {
43+
[$relation, $leafProperty] = explode('.', $property, 2);
44+
if (!in_array($relation, $queryBuilder->getAllAliases(), true)) {
45+
$queryBuilder->leftJoin($rootAlias.'.'.$relation, $relation);
46+
}
47+
$queryBuilder
48+
->andWhere(sprintf('%s.%s = :%s', $relation, $leafProperty, $parameter))
49+
->setParameter($parameter, $value);
50+
51+
return;
52+
}
53+
54+
$queryBuilder
55+
->andWhere(sprintf('%s.%s = :%s', $rootAlias, $property, $parameter))
56+
->setParameter($parameter, $value);
3257
}
3358
}

0 commit comments

Comments
 (0)