Skip to content

Commit

Permalink
09 - Add a list representation for locations in the admin interface
Browse files Browse the repository at this point in the history
  • Loading branch information
wachterjohannes authored and niklasnatter committed Oct 17, 2022
1 parent f635af0 commit b2fe808
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 2 deletions.
41 changes: 41 additions & 0 deletions config/lists/locations.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" ?>
<list xmlns="http://schemas.sulu.io/list-builder/list">
<key>locations</key>

<properties>
<property name="id" visibility="no" translation="sulu_admin.id">
<field-name>id</field-name>
<entity-name>App\Entity\Location</entity-name>
</property>

<property name="name" visibility="always" searchability="yes" translation="sulu_admin.name">
<field-name>name</field-name>
<entity-name>App\Entity\Location</entity-name>
</property>

<property name="street" visibility="yes" searchability="yes" translation="sulu_contact.street">
<field-name>street</field-name>
<entity-name>App\Entity\Location</entity-name>
</property>

<property name="number" visibility="yes" searchability="yes" translation="sulu_contact.number">
<field-name>number</field-name>
<entity-name>App\Entity\Location</entity-name>
</property>

<property name="postalCode" visibility="yes" searchability="yes" translation="sulu_contact.zip">
<field-name>postalCode</field-name>
<entity-name>App\Entity\Location</entity-name>
</property>

<property name="city" visibility="yes" searchability="yes" translation="sulu_contact.city">
<field-name>city</field-name>
<entity-name>App\Entity\Location</entity-name>
</property>

<property name="countryCode" visibility="yes" searchability="yes" translation="sulu_contact.country">
<field-name>countryCode</field-name>
<entity-name>App\Entity\Location</entity-name>
</property>
</properties>
</list>
4 changes: 4 additions & 0 deletions config/packages/sulu_admin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ sulu_admin:
routes:
list: app.get_event_registration_list

locations:
routes:
list: app.get_location_list

# Registering Selection Field Types in this section
field_type_options:
selection:
Expand Down
46 changes: 46 additions & 0 deletions src/Admin/LocationAdmin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace App\Admin;

use App\Entity\Location;
use Sulu\Bundle\AdminBundle\Admin\Admin;
use Sulu\Bundle\AdminBundle\Admin\Navigation\NavigationItem;
use Sulu\Bundle\AdminBundle\Admin\Navigation\NavigationItemCollection;
use Sulu\Bundle\AdminBundle\Admin\View\ViewBuilderFactoryInterface;
use Sulu\Bundle\AdminBundle\Admin\View\ViewCollection;

class LocationAdmin extends Admin
{
final public const LOCATION_LIST_KEY = 'locations';

final public const LOCATION_LIST_VIEW = 'app.locations_list';

public function __construct(
private readonly ViewBuilderFactoryInterface $viewBuilderFactory,
) {
}

public function configureNavigationItems(NavigationItemCollection $navigationItemCollection): void
{
$module = $navigationItemCollection->get('app.events');

$locations = new NavigationItem('app.locations');
$locations->setPosition(10);
$locations->setView(static::LOCATION_LIST_VIEW);

$module->addChild($locations);
}

public function configureViews(ViewCollection $viewCollection): void
{
$listView = $this->viewBuilderFactory->createListViewBuilder(self::LOCATION_LIST_VIEW, '/locations')
->setResourceKey(Location::RESOURCE_KEY)
->setListKey(self::LOCATION_LIST_KEY)
->setTitle('app.locations')
->addListAdapters(['table'])
->addToolbarActions([]);
$viewCollection->add($listView);
}
}
29 changes: 29 additions & 0 deletions src/Controller/Admin/LocationController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace App\Controller\Admin;

use App\Common\DoctrineListRepresentationFactory;
use App\Entity\Location;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class LocationController extends AbstractController
{
public function __construct(
private readonly DoctrineListRepresentationFactory $doctrineListRepresentationFactory,
) {
}

#[Route(path: '/admin/api/locations', methods: ['GET'], name: 'app.get_location_list')]
public function getListAction(): Response
{
$listRepresentation = $this->doctrineListRepresentationFactory->createDoctrineListRepresentation(
Location::RESOURCE_KEY,
);

return $this->json($listRepresentation->toArray());
}
}
2 changes: 2 additions & 0 deletions src/Entity/Location.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#[ORM\Entity(repositoryClass: LocationRepository::class)]
class Location
{
final public const RESOURCE_KEY = 'locations';

#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: Types::INTEGER)]
Expand Down
57 changes: 57 additions & 0 deletions tests/Functional/Controller/Admin/LocationControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace App\Tests\Functional\Controller\Admin;

use App\Tests\Functional\Traits\LocationTrait;
use Sulu\Bundle\TestBundle\Testing\SuluTestCase;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Component\HttpFoundation\Response;

class LocationControllerTest extends SuluTestCase
{
use LocationTrait;

private KernelBrowser $client;

protected function setUp(): void
{
$this->client = $this->createAuthenticatedClient();
$this->purgeDatabase();
}

public function testGetList(): void
{
$location1 = $this->createLocation('Sulu');
$location2 = $this->createLocation('Symfony');

$this->client->jsonRequest('GET', '/admin/api/locations');

$response = $this->client->getResponse();
$this->assertInstanceOf(Response::class, $response);
/**
* @var array{
* _embedded: array{
* locations: array<array{
* id: int,
* name: string,
* }>
* },
* total: int,
* } $result
*/
$result = \json_decode($response->getContent() ?: '', true, 512, \JSON_THROW_ON_ERROR);
$this->assertHttpStatusCode(200, $response);

$this->assertSame(2, $result['total']);
$this->assertCount(2, $result['_embedded']['locations']);
$items = $result['_embedded']['locations'];

$this->assertSame($location1->getId(), $items[0]['id']);
$this->assertSame($location2->getId(), $items[1]['id']);

$this->assertSame($location1->getName(), $items[0]['name']);
$this->assertSame($location2->getName(), $items[1]['name']);
}
}
35 changes: 35 additions & 0 deletions tests/Functional/Traits/LocationTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace App\Tests\Functional\Traits;

use App\Entity\Location;
use App\Repository\LocationRepository;
use Doctrine\ORM\EntityManagerInterface;

trait LocationTrait
{
public function createLocation(string $name): Location
{
$location = $this->getLocationRepository()->create();
$location->setName($name);
$location->setStreet('');
$location->setNumber('');
$location->setPostalCode('');
$location->setCity('');
$location->setCountryCode('');

static::getEntityManager()->persist($location);
static::getEntityManager()->flush();

return $location;
}

protected function getLocationRepository(): LocationRepository
{
return static::getEntityManager()->getRepository(Location::class);
}

abstract protected static function getEntityManager(): EntityManagerInterface;
}
3 changes: 2 additions & 1 deletion translations/admin.de.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
"app.end_date": "Ende",
"app.enable_event": "Veranstaltungen aktivieren",
"app.enabled": "Aktiviert",
"app.location": "Standort"
"app.location": "Standort",
"app.locations": "Standorte"
}
3 changes: 2 additions & 1 deletion translations/admin.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
"app.end_date": "Ende",
"app.enable_event": "Enable event",
"app.enabled": "Enabled",
"app.location": "Location"
"app.location": "Location",
"app.locations": "Locations"
}

0 comments on commit b2fe808

Please sign in to comment.