Browse Source

backports murph-skeleton

develop
Simon Vieille 1 month ago
parent
commit
fcd9288e60
  1. 6
      config/services.yaml
  2. 44
      core/Controller/Admin/Crud/CrudController.php
  3. 15
      core/Crud/Field/Field.php
  4. 43
      core/Resources/views/admin/crud/index.html.twig

6
config/services.yaml

@ -26,8 +26,10 @@ services:
- '../src/Kernel.php'
- '../src/Tests/'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Core\Maker\:
resource: '../core/Maker/'
tags: ['maker.command']
App\Core\Controller\:
resource: '../core/Controller/'
tags: ['controller.service_arguments']

44
core/Controller/Admin/Crud/CrudController.php

@ -19,6 +19,10 @@ use Symfony\Component\HttpFoundation\Session\Session;
abstract class CrudController extends AdminController
{
protected array $filters = [];
protected array $sort = [
'label' => null,
'direction' => null,
];
abstract protected function getConfiguration(): CrudConfiguration;
@ -26,7 +30,7 @@ abstract class CrudController extends AdminController
{
$configuration = $this->getConfiguration();
$this->updateFilters($request, $session);
$this->applySort('index', $query, $request);
$pager = $query
->useFilters($this->filters)
@ -36,6 +40,7 @@ abstract class CrudController extends AdminController
return $this->render($this->getConfiguration()->getView('index'), [
'configuration' => $configuration,
'pager' => $pager,
'sort' => $this->sort,
'filters' => [
'show' => null !== $configuration->getForm('filter'),
'isEmpty' => empty($this->filters),
@ -198,4 +203,41 @@ abstract class CrudController extends AdminController
}
}
}
protected function applySort(string $context, RepositoryQuery $query, Request $request)
{
$configuration = $this->getConfiguration();
$name = $request->query->get('_sort');
$direction = strtolower($request->query->get('_sort_direction'));
if (!in_array($direction, ['asc', 'desc'])) {
$direction = 'asc';
}
foreach ($configuration->getFields($context) as $label => $field) {
$sortOption = $field['options']['sort'] ?? null;
if (null === $sortOption) {
continue;
}
if ($sortOption[0] !== $name) {
continue;
}
$sorter = $sortOption[1];
if (is_string($sorter)) {
$query->orderBy($sorter, $direction);
} else {
call_user_func_array($sorter, [$query, $direction]);
}
$this->sort = [
'label' => $label,
'direction' => $direction,
];
}
}
}

15
core/Crud/Field/Field.php

@ -30,6 +30,7 @@ abstract class Field
'property_builder' => null,
'view' => null,
'raw' => false,
'sort' => null,
'attr' => [],
]);
@ -39,6 +40,20 @@ abstract class Field
$resolver->setAllowedTypes('attr', 'array');
$resolver->setAllowedTypes('raw', 'boolean');
$resolver->setAllowedTypes('property_builder', ['null', 'callable']);
$resolver->setAllowedValues('sort', function($value) {
if ($value === null) {
return true;
}
if (!is_array($value)) {
return false;
}
$isValidParam1 = !empty($value[0]) && is_string($value[0]);
$isValidParam2 = !empty($value[1]) && (is_string($value[1]) || is_callable($value[1]));
return $isValidParam1 && $isValidParam2;
});
return $resolver;
}

43
core/Resources/views/admin/crud/index.html.twig

@ -51,12 +51,51 @@
<tr>
{% for label, config in configuration.fields('index') %}
{% set attr = config.options.attr is defined ? config.options.attr : [] %}
{% set isSortable = config.options.sort ?? false %}
<th {% for key, value in attr %}{{ key }}="{{ value }}"{% endfor %}>
{{ label|trans }}
{% if isSortable %}
{% if sort %}
{% if sort.label == label %}
{% if sort.direction == 'asc' %}
{% set newDirection = 'desc' %}
{% set icon = 'fa fa-sort-amount-down-alt' %}
{% else %}
{% set newDirection = 'asc' %}
{% set icon = 'fa fa-sort-amount-up-alt' %}
{% endif %}
{% set url = path(configuration.getPageRoute('index'), {
_sort: config.options.sort[0],
_sort_direction: newDirection,
}) %}
{% else %}
{% set url = path(configuration.getPageRoute('index'), {
_sort: config.options.sort[0],
_sort_direction: 'asc',
}) %}
{% set icon = null %}
{% endif %}
<a href="{{ url }}">
{% if icon is defined %}
<span class="{{ icon }}"></span>
{% endif %}
{{ label|trans }}
</a>
{% else %}
{{ label|trans }}
{% endif %}
{% else %}
{{ label|trans }}
{% endif %}
</th>
{% endfor %}
<th class="col-2 miw-100 text-right">Actions</th>
<th class="col-2 miw-100 text-right">
{{ 'Actions'|trans }}
</th>
</tr>
</thead>
{% endblock %}

Loading…
Cancel
Save