feat(crud): add the option "inline_form" in fields

feat(crud): allows to enable and disable double click listener on a table row

feat(crud): update de template of the controller
This commit is contained in:
Simon Vieille 2023-04-14 07:09:57 +02:00
parent 42ab4d85f0
commit b915b8b3ed
Signed by: deblan
GPG key ID: 579388D585F70417
6 changed files with 113 additions and 10 deletions

View file

@ -127,6 +127,51 @@ abstract class CrudController extends AdminController
]);
}
protected function doInlineEdit(string $context, string $label, EntityInterface $entity, EntityManager $entityManager, Request $request, callable $beforeUpdate = null): Response
{
$configuration = $this->getConfiguration();
$this->prepareEntity($entity);
$builder = $this->createFormBuilder($entity);
$callback = $configuration->getFields($context)[$label]['options']['inline_form'] ?? null;
if (null === $callback) {
throw $this->createNotFoundException();
}
call_user_func_array($callback, [$builder, $entity]);
$form = $builder->getForm();
$redirectTo = $request->query->get('redirectTo');
if ($request->isMethod('POST')) {
$form->handleRequest($request);
if ($form->isValid()) {
if (null !== $beforeUpdate) {
call_user_func_array($beforeUpdate, [$entity, $form, $request]);
}
$entityManager->update($entity);
$this->addFlash('success', 'The data has been saved.');
} else {
$this->addFlash('warning', 'The form is not valid.');
}
return $this->redirect($redirectTo);
}
return $this->render('@Core/admin/crud/inline_edit.html.twig', [
'form' => $form->createView(),
'configuration' => $configuration,
'entity' => $entity,
'context' => $context,
'label' => $label,
'redirectTo' => $redirectTo,
]);
}
protected function doSort(int $page, RepositoryQuery $query, EntityManager $entityManager, Request $request, Session $session): Response
{
$configuration = $this->getConfiguration();

View file

@ -17,6 +17,7 @@ class CrudConfiguration
protected array $actionTitles = [];
protected array $forms = [];
protected array $formOptions = [];
protected array $inlineForms = [];
protected array $views = [];
protected array $viewDatas = [];
protected array $fields = [];
@ -252,7 +253,7 @@ class CrudConfiguration
/* -- */
public function setMaxPerPage(string $page, int $max)
public function setMaxPerPage(string $page, int $max): self
{
$this->maxPerPage[$page] = $max;
@ -266,6 +267,20 @@ class CrudConfiguration
/* -- */
public function setDoubleClick(string $page, bool $enabled): bool
{
$this->doubleClick[$page] = $enabled;
return $this;
}
public function getDoubleClick(string $page): bool
{
return $this->doubleClick[$page] ?? false;
}
/* -- */
public function setI18n(array $locales, string $defaultLocale): self
{
$this->locales = $locales;

View file

@ -29,18 +29,22 @@ abstract class Field
'property' => null,
'property_builder' => null,
'view' => null,
'action' => null,
'raw' => false,
'sort' => null,
'href' => null,
'href_attr' => [],
'attr' => [],
'inline_form' => null,
]);
$resolver->setRequired('view');
$resolver->setAllowedTypes('property', ['null', 'string']);
$resolver->setAllowedTypes('view', 'string');
$resolver->setAllowedTypes('action', ['null', 'string']);
$resolver->setAllowedTypes('attr', 'array');
$resolver->setAllowedTypes('href', ['null', 'string', 'callable']);
$resolver->setAllowedTypes('inline_form', ['null', 'callable']);
$resolver->setAllowedTypes('href_attr', 'array', 'callable');
$resolver->setAllowedTypes('raw', 'boolean');
$resolver->setAllowedTypes('property_builder', ['null', 'callable']);

View file

@ -50,6 +50,12 @@ class <?= $class_name; ?> extends CrudController
return $this->doEdit($entity, $entityManager, $request);
}
#[Route(path: "/admin/<?= $route; ?>/inline_edit/{entity}/{context}/{label}", name: 'admin_<?= $route; ?>_inline_edit', methods: ['GET', 'POST'])]
public function inlineEdit(string $context, string $label, Entity $entity, EntityManager $entityManager, Request $request): Response
{
return $this->doInlineEdit($context, $label, $entity, $entityManager, $request);
}
#[Route(path: "/admin/<?= $route; ?>/sort/{page}", name: "admin_<?= $route; ?>_sort", methods: ['POST'], requirements: ['page' => '\d+'])]
public function sort(RepositoryQuery $query, EntityManager $entityManager, Request $request, Session $session, int $page = 1): Response
{
@ -79,6 +85,7 @@ class <?= $class_name; ?> extends CrudController
->setPageRoute('index', 'admin_<?= $route; ?>_index')
->setPageRoute('new', 'admin_<?= $route; ?>_new')
->setPageRoute('edit', 'admin_<?= $route; ?>_edit')
->setPageRoute('inline_edit', 'admin_<?= $route; ?>_inline_edit')
->setPageRoute('show', 'admin_<?= $route; ?>_show')
->setPageRoute('sort', 'admin_<?= $route; ?>_sort')
->setPageRoute('batch', 'admin_<?= $route; ?>_batch')
@ -98,6 +105,7 @@ class <?= $class_name; ?> extends CrudController
// ->setAction('index', 'show', true)
// ->setAction('index', 'edit', true)
// ->setAction('index', 'delete', true)
// ->setDoubleClick('index', false)
// ->setAction('edit', 'back', true)
// ->setAction('edit', 'show', true)

View file

@ -185,25 +185,36 @@
{% endif %}
{% endset -%}
<tr {{ dataSortableItem|raw }} data-dblclick="{{ dbClick }}" class="{{ loop.index is odd ? 'is-odd' : 'is-even' }}">
<tr {{ dataSortableItem|raw }} {% if configuration.doubleClick(context) %}data-dblclick="{{ dbClick }}"{% endif %} class="{{ loop.index is odd ? 'is-odd' : 'is-even' }}">
{% if configuration.hasBatchAction(context) %}
<td class="crud-batch-column">
<input type="checkbox" class="batch_form" name="batch[items][{{ loop.index }}]" form="form-batch" value="{{ loop.index }}">
</td>
{% endif %}
{% for config in configuration.fields(context) %}
{% set attr = config.options.attr is defined ? config.options.attr : [] %}
{% set action = config.options.action is defined ? config.options.action : null %}
{% for label, config in configuration.fields(context) %}
{% set attr = config.options.attr ?? [] %}
{% set action = config.options.action ?? null %}
{% set inlineForm = config.options.inline_form ?? null %}
<td {% for key, value in attr %}{{ key }}="{{ value }}"{% endfor %}>
{% if action == 'show' %}
<a href="{{ path(configuration.pageRoute('show'), {entity: item.id}) }}">
{% if inlineForm and configuration.action(context, 'edit', true, [item]) %}
<a href="#" data-modal="{{ path(
configuration.pageroute('inline_edit'), {
entity: item.id,
context: context,
label: label,
redirectTo: app.request.uri,
}|merge(configuration.pagerouteparams('inline_edit'))) }}" data-modal-create>
{{ render_field(item, config, configuration.defaultlocale) }}
</a>
{% elseif action == 'show' and configuration.action(context, 'show', true, [item]) %}
<a href="{{ path(configuration.pageRoute('show'), {entity: item.id}|merge(configuration.pageRouteParams('show'))) }}">
{{ render_field(item, config, configuration.defaultLocale) }}
</a>
{% elseif action == 'edit' %}
<a href="{{ path(configuration.pageRoute('edit'), {entity: item.id}) }}">
{{ render_field(item, config, configuration.defaultLocale) }}
{% elseif action == 'edit' and configuration.action(context, 'edit', true, [item]) %}
<a href="{{ path(configuration.pageroute('edit'), {entity: item.id}|merge(configuration.pagerouteparams('edit'))) }}">
{{ render_field(item, config, configuration.defaultlocale) }}
</a>
{% else %}
{{ render_field(item, config, configuration.defaultLocale) }}

View file

@ -0,0 +1,20 @@
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{{ label }}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form action="{{ path(configuration.pageRoute('inline_edit'), {entity: entity.id, context: context, label: label, redirectTo, redirectTo}|merge(configuration.pageRouteParams('inline_edit'))) }}" id="form-entity-edit" method="POST">
{{ include('@Core/setting/setting_admin/_form.html.twig') }}
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ 'Cancel'|trans }}</button>
<button type="submit" form="form-entity-edit" class="btn btn-primary">{{ 'Save'|trans }}</button>
</div>
</div>
</div>