added section name for meta-fields positioning (#5747)
This commit is contained in:
@@ -12,8 +12,8 @@ namespace App\Entity;
|
|||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @method getTags() array
|
* @method array<Tag> getTags()
|
||||||
* @method getBreak() int
|
* @method int getBreak()
|
||||||
*/
|
*/
|
||||||
interface ExportableItem
|
interface ExportableItem
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ namespace App\Entity;
|
|||||||
|
|
||||||
use Symfony\Component\Validator\Constraint;
|
use Symfony\Component\Validator\Constraint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method null|string getSection()
|
||||||
|
* @method void setSection(?string $name)
|
||||||
|
*/
|
||||||
interface MetaTableTypeInterface
|
interface MetaTableTypeInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -43,6 +47,8 @@ interface MetaTableTypeInterface
|
|||||||
/**
|
/**
|
||||||
* This will merge the current object with the values from the given $meta instance.
|
* This will merge the current object with the values from the given $meta instance.
|
||||||
* It should NOT update the name or value, but only the form settings.
|
* It should NOT update the name or value, but only the form settings.
|
||||||
|
*
|
||||||
|
* Settings from the given $meta object will win over the current ones.
|
||||||
*/
|
*/
|
||||||
public function merge(MetaTableTypeInterface $meta): MetaTableTypeInterface;
|
public function merge(MetaTableTypeInterface $meta): MetaTableTypeInterface;
|
||||||
|
|
||||||
@@ -132,6 +138,16 @@ interface MetaTableTypeInterface
|
|||||||
*/
|
*/
|
||||||
public function getOrder(): int;
|
public function getOrder(): int;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME activate with 3.0
|
||||||
|
*/
|
||||||
|
//public function setSection(?string $section): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME activate with 3.0
|
||||||
|
*/
|
||||||
|
//public function getSection(): ?string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether true if this field is defined by a plugin, or false if it is a value stored in the database.
|
* Whether true if this field is defined by a plugin, or false if it is a value stored in the database.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ trait MetaTableTypeTrait
|
|||||||
*/
|
*/
|
||||||
private mixed $data = null;
|
private mixed $data = null;
|
||||||
private bool $updated = false;
|
private bool $updated = false;
|
||||||
|
private ?string $section = null;
|
||||||
|
|
||||||
public function getName(): ?string
|
public function getName(): ?string
|
||||||
{
|
{
|
||||||
@@ -193,13 +194,11 @@ trait MetaTableTypeTrait
|
|||||||
|
|
||||||
public function merge(MetaTableTypeInterface $meta): MetaTableTypeInterface
|
public function merge(MetaTableTypeInterface $meta): MetaTableTypeInterface
|
||||||
{
|
{
|
||||||
$this
|
$this->setConstraints($meta->getConstraints());
|
||||||
->setConstraints($meta->getConstraints())
|
$this->setIsRequired($meta->isRequired());
|
||||||
->setIsRequired($meta->isRequired())
|
$this->setIsVisible($meta->isVisible());
|
||||||
->setIsVisible($meta->isVisible())
|
$this->setOptions($meta->getOptions());
|
||||||
->setOptions($meta->getOptions())
|
$this->setOrder($meta->getOrder());
|
||||||
->setOrder($meta->getOrder())
|
|
||||||
;
|
|
||||||
|
|
||||||
if ($meta->getLabel() !== null) {
|
if ($meta->getLabel() !== null) {
|
||||||
$this->setLabel($meta->getLabel());
|
$this->setLabel($meta->getLabel());
|
||||||
@@ -209,6 +208,10 @@ trait MetaTableTypeTrait
|
|||||||
$this->setType($meta->getType());
|
$this->setType($meta->getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($meta->getSection() !== null) {
|
||||||
|
$this->setSection($meta->getSection());
|
||||||
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,6 +269,16 @@ trait MetaTableTypeTrait
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setSection(?string $section): void
|
||||||
|
{
|
||||||
|
$this->section = $section;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSection(): ?string
|
||||||
|
{
|
||||||
|
return $this->section;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this field is defined by a plugin or just a value stored in the database.
|
* Whether this field is defined by a plugin or just a value stored in the database.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ use App\Repository\Query\TimesheetQuery;
|
|||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO change interface for 3.0
|
* FIXME change interface for 3.0
|
||||||
* @method getType() string
|
* @method string getType()
|
||||||
* @method isInternal() bool
|
* @method bool isInternal()
|
||||||
*/
|
*/
|
||||||
interface ExportRendererInterface
|
interface ExportRendererInterface
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
'back': path('admin_activity')
|
'back': path('admin_activity')
|
||||||
} %}
|
} %}
|
||||||
{% embed formEditTemplate with formOptions %}
|
{% embed formEditTemplate with formOptions %}
|
||||||
|
{% import "macros/form_helper.html.twig" as form_helper %}
|
||||||
{% block form_body %}
|
{% block form_body %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
@@ -49,6 +50,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{{ form_helper.metafields(form, null) }}
|
||||||
|
{% embed '@theme/embeds/collapsible.html.twig' with {id: 'activity_invoice_settings'} %}
|
||||||
|
{% import "macros/widgets.html.twig" as widgets %}
|
||||||
|
{% import "macros/form_helper.html.twig" as form_helper %}
|
||||||
|
{% block title %}{{ 'invoices'|trans }}{% endblock %}
|
||||||
|
{% block body %}
|
||||||
|
{% if form.invoiceText is defined %}
|
||||||
|
{{ form_row(form.invoiceText) }}
|
||||||
|
{% endif %}
|
||||||
|
{{ form_helper.metafields(form, 'invoice') }}
|
||||||
|
{% endblock %}
|
||||||
|
{% endembed %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
{{ form_row(form.visible) }}
|
{{ form_row(form.visible) }}
|
||||||
@@ -57,18 +70,6 @@
|
|||||||
{{ form_row(form.billable) }}
|
{{ form_row(form.billable) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if form.metaFields is defined and form.metaFields is not empty %}
|
|
||||||
{{ form_row(form.metaFields) }}
|
|
||||||
{% endif %}
|
|
||||||
{% embed '@theme/embeds/collapsible.html.twig' with {id: 'activity_invoice_settings'} %}
|
|
||||||
{% import "macros/widgets.html.twig" as widgets %}
|
|
||||||
{% block title %}{{ 'invoices'|trans }}{% endblock %}
|
|
||||||
{% block body %}
|
|
||||||
{% if form.invoiceText is defined %}
|
|
||||||
{{ form_row(form.invoiceText) }}
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
||||||
{% endembed %}
|
|
||||||
{{ form_rest(form) }}
|
{{ form_rest(form) }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% endembed %}
|
{% endembed %}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
'back': path('admin_customer')
|
'back': path('admin_customer')
|
||||||
} %}
|
} %}
|
||||||
{% embed formEditTemplate with formOptions %}
|
{% embed formEditTemplate with formOptions %}
|
||||||
|
{% import "macros/form_helper.html.twig" as form_helper %}
|
||||||
{% block form_body %}
|
{% block form_body %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
@@ -75,11 +76,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if form.metaFields is defined and form.metaFields is not empty %}
|
{{ form_helper.metafields(form, null) }}
|
||||||
{{ form_row(form.metaFields) }}
|
|
||||||
{% endif %}
|
|
||||||
{% embed '@theme/embeds/collapsible.html.twig' with {id: 'customer_address_settings'} %}
|
{% embed '@theme/embeds/collapsible.html.twig' with {id: 'customer_address_settings'} %}
|
||||||
{% import "macros/widgets.html.twig" as widgets %}
|
{% import "macros/widgets.html.twig" as widgets %}
|
||||||
|
{% import "macros/form_helper.html.twig" as form_helper %}
|
||||||
{% block title %}{{ 'address'|trans }}{% endblock %}
|
{% block title %}{{ 'address'|trans }}{% endblock %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -125,11 +125,12 @@
|
|||||||
{{ form_row(form.timezone) }}
|
{{ form_row(form.timezone) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{ form_helper.metafields(form, 'address') }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% endembed %}
|
{% endembed %}
|
||||||
{% embed '@theme/embeds/collapsible.html.twig' with {id: 'customer_invoice_settings'} %}
|
{% embed '@theme/embeds/collapsible.html.twig' with {id: 'customer_invoice_settings'} %}
|
||||||
{% import "macros/widgets.html.twig" as widgets %}
|
{% import "macros/widgets.html.twig" as widgets %}
|
||||||
|
{% import "macros/form_helper.html.twig" as form_helper %}
|
||||||
{% block title %}{{ 'invoices'|trans }}{% endblock %}
|
{% block title %}{{ 'invoices'|trans }}{% endblock %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
{% if form.buyerReference is defined %}
|
{% if form.buyerReference is defined %}
|
||||||
@@ -141,6 +142,7 @@
|
|||||||
{% if form.invoiceText is defined %}
|
{% if form.invoiceText is defined %}
|
||||||
{{ form_row(form.invoiceText) }}
|
{{ form_row(form.invoiceText) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{{ form_helper.metafields(form, 'invoice') }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% endembed %}
|
{% endembed %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -474,7 +474,9 @@
|
|||||||
|
|
||||||
{%- block meta_fields_collection_widget -%}
|
{%- block meta_fields_collection_widget -%}
|
||||||
{% for meta in form|sort((a, b) => a.vars.data.order <=> b.vars.data.order) %}
|
{% for meta in form|sort((a, b) => a.vars.data.order <=> b.vars.data.order) %}
|
||||||
{{ form_row(meta.value, {'row_attr': {'class': 'mb-3 ' ~ form.parent.vars.name ~ '_row_' ~ form.vars.name ~ '_' ~ meta.vars.name}}) }}
|
{% if not meta.rendered %}
|
||||||
|
{{ form_row(meta.value, {'row_attr': {'class': 'mb-3 ' ~ form.parent.vars.name ~ '_row_' ~ form.vars.name ~ '_' ~ meta.vars.name}}) }}
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{%- endblock meta_fields_collection_widget %}
|
{%- endblock meta_fields_collection_widget %}
|
||||||
|
|
||||||
|
|||||||
7
templates/macros/form_helper.html.twig
Normal file
7
templates/macros/form_helper.html.twig
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{% macro metafields(form, section) %}
|
||||||
|
{% for meta in form.metaFields|sort((a, b) => a.vars.data.order <=> b.vars.data.order) %}
|
||||||
|
{% if meta.vars.data.section is same as (section) %}
|
||||||
|
{{ form_row(meta.value, {'row_attr': {'class': 'mb-3 ' ~ form.vars.name ~ '_row_' ~ form.metaFields.vars.name ~ '_' ~ meta.vars.name}}) }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endmacro %}
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
'back': path('admin_project')
|
'back': path('admin_project')
|
||||||
} %}
|
} %}
|
||||||
{% embed formEditTemplate with formOptions %}
|
{% embed formEditTemplate with formOptions %}
|
||||||
|
{% import "macros/form_helper.html.twig" as form_helper %}
|
||||||
{% block form_body %}
|
{% block form_body %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
@@ -58,11 +59,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if form.metaFields is defined and form.metaFields is not empty %}
|
{{ form_helper.metafields(form, null) }}
|
||||||
{{ form_row(form.metaFields) }}
|
|
||||||
{% endif %}
|
|
||||||
{% embed '@theme/embeds/collapsible.html.twig' with {id: 'project_invoice_settings'} %}
|
{% embed '@theme/embeds/collapsible.html.twig' with {id: 'project_invoice_settings'} %}
|
||||||
{% import "macros/widgets.html.twig" as widgets %}
|
{% import "macros/widgets.html.twig" as widgets %}
|
||||||
|
{% import "macros/form_helper.html.twig" as form_helper %}
|
||||||
{% block title %}{{ 'invoices'|trans }}{% endblock %}
|
{% block title %}{{ 'invoices'|trans }}{% endblock %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -76,6 +76,7 @@
|
|||||||
{% if form.invoiceText is defined %}
|
{% if form.invoiceText is defined %}
|
||||||
{{ form_row(form.invoiceText) }}
|
{{ form_row(form.invoiceText) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{{ form_helper.metafields(form, 'invoice') }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% endembed %}
|
{% endembed %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ abstract class AbstractMetaEntityTestCase extends TestCase
|
|||||||
self::assertFalse($sut->isVisible());
|
self::assertFalse($sut->isVisible());
|
||||||
self::assertFalse($sut->isRequired());
|
self::assertFalse($sut->isRequired());
|
||||||
self::assertEquals(0, $sut->getOrder());
|
self::assertEquals(0, $sut->getOrder());
|
||||||
|
self::assertNull($sut->getSection());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSetterAndGetter(): void
|
public function testSetterAndGetter(): void
|
||||||
@@ -83,6 +84,11 @@ abstract class AbstractMetaEntityTestCase extends TestCase
|
|||||||
$entity = $this->getEntity();
|
$entity = $this->getEntity();
|
||||||
self::assertInstanceOf(MetaTableTypeInterface::class, $sut->setEntity($entity));
|
self::assertInstanceOf(MetaTableTypeInterface::class, $sut->setEntity($entity));
|
||||||
self::assertSame($entity, $sut->getEntity());
|
self::assertSame($entity, $sut->getEntity());
|
||||||
|
|
||||||
|
$sut->setSection('foo');
|
||||||
|
self::assertEquals('foo', $sut->getSection());
|
||||||
|
$sut->setSection(null);
|
||||||
|
self::assertNull($sut->getSection());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMerge(): void
|
public function testMerge(): void
|
||||||
@@ -90,18 +96,19 @@ abstract class AbstractMetaEntityTestCase extends TestCase
|
|||||||
$entity1 = $this->getEntity();
|
$entity1 = $this->getEntity();
|
||||||
$entity2 = $this->getEntity();
|
$entity2 = $this->getEntity();
|
||||||
$meta1 = $this->getMetaEntity();
|
$meta1 = $this->getMetaEntity();
|
||||||
$meta1
|
$meta1->setName('foo');
|
||||||
->setName('foo')
|
$meta1->setValue('bar');
|
||||||
->setValue('bar')
|
$meta1->setType('blub');
|
||||||
->setType('blub')
|
$meta1->setEntity($entity1);
|
||||||
->setEntity($entity1)
|
$meta1->setConstraints([new NotNull()]);
|
||||||
->setConstraints([new NotNull()])
|
$meta1->setOptions(['foo' => 'bar', 'bar' => 'foo']);
|
||||||
->setOptions(['foo' => 'bar', 'bar' => 'foo'])
|
$meta1->setSection('hello');
|
||||||
;
|
|
||||||
self::assertEquals('foo', $meta1->getName());
|
self::assertEquals('foo', $meta1->getName());
|
||||||
self::assertEquals('bar', $meta1->getValue());
|
self::assertEquals('bar', $meta1->getValue());
|
||||||
self::assertEquals('blub', $meta1->getType());
|
self::assertEquals('blub', $meta1->getType());
|
||||||
self::assertEquals('foo', $meta1->getLabel());
|
self::assertEquals('foo', $meta1->getLabel());
|
||||||
|
self::assertEquals('hello', $meta1->getSection());
|
||||||
self::assertFalse($meta1->isRequired());
|
self::assertFalse($meta1->isRequired());
|
||||||
self::assertFalse($meta1->isVisible());
|
self::assertFalse($meta1->isVisible());
|
||||||
self::assertSame($entity1, $meta1->getEntity());
|
self::assertSame($entity1, $meta1->getEntity());
|
||||||
@@ -109,18 +116,17 @@ abstract class AbstractMetaEntityTestCase extends TestCase
|
|||||||
self::assertCount(2, $meta1->getOptions());
|
self::assertCount(2, $meta1->getOptions());
|
||||||
|
|
||||||
$meta2 = $this->getMetaEntity();
|
$meta2 = $this->getMetaEntity();
|
||||||
$meta2
|
$meta2->setName('foo2');
|
||||||
->setName('foo2')
|
$meta2->setLabel('TRALALA');
|
||||||
->setLabel('TRALALA')
|
$meta2->setValue('bar2');
|
||||||
->setValue('bar2')
|
$meta2->setType('blub2');
|
||||||
->setType('blub2')
|
$meta2->setSection('world');
|
||||||
->setEntity($entity2)
|
$meta2->setEntity($entity2);
|
||||||
->setIsRequired(true)
|
$meta2->setIsRequired(true);
|
||||||
->setIsVisible(true)
|
$meta2->setIsVisible(true);
|
||||||
->setOrder(93)
|
$meta2->setOrder(93);
|
||||||
->setConstraints([new NotBlank(), new Length(['min' => 1])])
|
$meta2->setConstraints([new NotBlank(), new Length(['min' => 1])]);
|
||||||
->setOptions(['foo1' => 'bar1'])
|
$meta2->setOptions(['foo1' => 'bar1']);
|
||||||
;
|
|
||||||
|
|
||||||
self::assertInstanceOf(MetaTableTypeInterface::class, $meta1->merge($meta2));
|
self::assertInstanceOf(MetaTableTypeInterface::class, $meta1->merge($meta2));
|
||||||
|
|
||||||
@@ -128,6 +134,7 @@ abstract class AbstractMetaEntityTestCase extends TestCase
|
|||||||
self::assertEquals('bar', $meta1->getValue());
|
self::assertEquals('bar', $meta1->getValue());
|
||||||
self::assertEquals('blub2', $meta1->getType());
|
self::assertEquals('blub2', $meta1->getType());
|
||||||
self::assertEquals('TRALALA', $meta1->getLabel());
|
self::assertEquals('TRALALA', $meta1->getLabel());
|
||||||
|
self::assertEquals('world', $meta1->getSection());
|
||||||
self::assertEquals(93, $meta1->getOrder());
|
self::assertEquals(93, $meta1->getOrder());
|
||||||
self::assertTrue($meta1->isRequired());
|
self::assertTrue($meta1->isRequired());
|
||||||
self::assertTrue($meta1->isVisible());
|
self::assertTrue($meta1->isVisible());
|
||||||
|
|||||||
Reference in New Issue
Block a user