feat: allow duplicate resource names, show the room next to the name
This commit is contained in:
1 parent
84724879c7
commit
d37d8bc786
8 files changed
+39
-21
No files matched your search
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
final class Version20260917130000 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Drops the unique (type, label) guard on resources';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('DROP INDEX uniq_resource_label ON resource');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('CREATE UNIQUE INDEX uniq_resource_label ON resource (type, label)');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,15 +7,12 @@ namespace App\Entity;
|
|||||||
use App\Enum\ResourceType;
|
use App\Enum\ResourceType;
|
||||||
use App\Repository\ResourceRepository;
|
use App\Repository\ResourceRepository;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A bookable thing: a desk, a parking spot or a portable device.
|
* A bookable thing: a desk, a parking spot or a portable device.
|
||||||
*/
|
*/
|
||||||
#[ORM\Entity(repositoryClass: ResourceRepository::class)]
|
#[ORM\Entity(repositoryClass: ResourceRepository::class)]
|
||||||
#[ORM\UniqueConstraint(name: 'uniq_resource_label', columns: ['type', 'label'])]
|
|
||||||
#[UniqueEntity(fields: ['type', 'label'], message: 'Diese Bezeichnung ist bereits vergeben.', errorPath: 'label')]
|
|
||||||
class Resource
|
class Resource
|
||||||
{
|
{
|
||||||
#[ORM\Id]
|
#[ORM\Id]
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<p>
|
<p>
|
||||||
{{ resource.type.label }} <em>{{ resource.label }}</em> wird endgültig gelöscht.
|
{{ resource.type.label }} <em>{{ resource.label }}</em>
|
||||||
|
{%- if resource.group %} ({{ resource.group.label }}){% endif %} wird endgültig gelöscht.
|
||||||
</p>
|
</p>
|
||||||
{% if upcoming > 0 or past > 0 %}
|
{% if upcoming > 0 or past > 0 %}
|
||||||
<p class="pt-2" data-booking-count>
|
<p class="pt-2" data-booking-count>
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
<p class="pb-4 text-sm text-gray-500">
|
<p class="pb-4 text-sm text-gray-500">
|
||||||
{{ resource.type.label }} · {{ resource.label }}
|
{{ resource.type.label }} · {{ resource.label }}
|
||||||
|
{%- if resource.group %} · {{ resource.group.label }}{% endif %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{% include 'booking/_fields.html.twig' %}
|
{% include 'booking/_fields.html.twig' %}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
<p class="pb-4 text-sm text-gray-500">
|
<p class="pb-4 text-sm text-gray-500">
|
||||||
{{ resource.type.label }} · {{ booking.date|format_datetime(pattern: 'EEEE, d. MMMM y') }}
|
{{ resource.type.label }} · {{ booking.date|format_datetime(pattern: 'EEEE, d. MMMM y') }}
|
||||||
|
{%- if resource.group %} · {{ resource.group.label }}{% endif %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{% if booking.partOfSeries %}
|
{% if booking.partOfSeries %}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<p>
|
<p>
|
||||||
{{ series.resource.label }} · {{ series.describe }}
|
{{ series.resource.label }}
|
||||||
|
{%- if series.resource.group %} ({{ series.resource.group.label }}){% endif %} · {{ series.describe }}
|
||||||
{% if series.user.id != app.user.id %}
|
{% if series.user.id != app.user.id %}
|
||||||
— Wiederkehrende Buchung von <em>{{ series.user.name }}</em>
|
— Wiederkehrende Buchung von <em>{{ series.user.name }}</em>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -33,7 +33,8 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
{% if tile.mine %}
|
{% if tile.mine %}
|
||||||
<span class="badge bg-primary text-white">{{ tile.mine.resource.label }}</span>
|
<span class="badge bg-primary text-white">{{ tile.mine.resource.label }}
|
||||||
|
{%- if tile.mine.resource.group %} · {{ tile.mine.resource.group.label }}{% endif %}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -82,28 +82,18 @@ class ResourceAdminControllerTest extends WebTestCase
|
|||||||
self::assertTrue($created->isActive());
|
self::assertTrue($created->isActive());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testADuplicateLabelIsRejectedInTheModal(): void
|
/**
|
||||||
|
* Labels are not unique: two desks may both be called "Schreibtisch 01", e.g. in different rooms.
|
||||||
|
*/
|
||||||
|
public function testADuplicateLabelIsAccepted(): void
|
||||||
{
|
{
|
||||||
$this->resource('Schreibtisch 01');
|
$this->resource('Schreibtisch 01');
|
||||||
$this->client->loginUser($this->admin());
|
$this->client->loginUser($this->admin());
|
||||||
|
|
||||||
$response = $this->submit('/admin/resources/new/desk', 'resource_form', ['label' => 'Schreibtisch 01']);
|
$response = $this->submit('/admin/resources/new/desk', 'resource_form', ['label' => 'Schreibtisch 01']);
|
||||||
|
|
||||||
self::assertSame(Response::HTTP_UNPROCESSABLE_ENTITY, $response->getStatusCode());
|
|
||||||
self::assertStringContainsString('bereits vergeben', (string) $response->getContent());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The same label is fine for another type -- uniqueness is per type, like the database's.
|
|
||||||
*/
|
|
||||||
public function testTheSameLabelMayExistForAnotherType(): void
|
|
||||||
{
|
|
||||||
$this->resource('A1');
|
|
||||||
$this->client->loginUser($this->admin());
|
|
||||||
|
|
||||||
$response = $this->submit('/admin/resources/new/parking', 'resource_form', ['label' => 'A1']);
|
|
||||||
|
|
||||||
self::assertSame('/admin/resources', $response->headers->get('HX-Redirect'));
|
self::assertSame('/admin/resources', $response->headers->get('HX-Redirect'));
|
||||||
|
self::assertCount(2, $this->em->getRepository(Resource::class)->findBy(['label' => 'Schreibtisch 01']));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in new issue
Block a user