backports murph-skeleton
This commit is contained in:
parent
b3c7f6b8ec
commit
fcd9288e60
|
@ -26,8 +26,10 @@ services:
|
||||||
- '../src/Kernel.php'
|
- '../src/Kernel.php'
|
||||||
- '../src/Tests/'
|
- '../src/Tests/'
|
||||||
|
|
||||||
# controllers are imported separately to make sure services can be injected
|
App\Core\Maker\:
|
||||||
# as action arguments even if you don't extend any base controller class
|
resource: '../core/Maker/'
|
||||||
|
tags: ['maker.command']
|
||||||
|
|
||||||
App\Core\Controller\:
|
App\Core\Controller\:
|
||||||
resource: '../core/Controller/'
|
resource: '../core/Controller/'
|
||||||
tags: ['controller.service_arguments']
|
tags: ['controller.service_arguments']
|
||||||
|
|
|
@ -19,6 +19,10 @@ use Symfony\Component\HttpFoundation\Session\Session;
|
||||||
abstract class CrudController extends AdminController
|
abstract class CrudController extends AdminController
|
||||||
{
|
{
|
||||||
protected array $filters = [];
|
protected array $filters = [];
|
||||||
|
protected array $sort = [
|
||||||
|
'label' => null,
|
||||||
|
'direction' => null,
|
||||||
|
];
|
||||||
|
|
||||||
abstract protected function getConfiguration(): CrudConfiguration;
|
abstract protected function getConfiguration(): CrudConfiguration;
|
||||||
|
|
||||||
|
@ -26,7 +30,7 @@ abstract class CrudController extends AdminController
|
||||||
{
|
{
|
||||||
$configuration = $this->getConfiguration();
|
$configuration = $this->getConfiguration();
|
||||||
|
|
||||||
$this->updateFilters($request, $session);
|
$this->applySort('index', $query, $request);
|
||||||
|
|
||||||
$pager = $query
|
$pager = $query
|
||||||
->useFilters($this->filters)
|
->useFilters($this->filters)
|
||||||
|
@ -36,6 +40,7 @@ abstract class CrudController extends AdminController
|
||||||
return $this->render($this->getConfiguration()->getView('index'), [
|
return $this->render($this->getConfiguration()->getView('index'), [
|
||||||
'configuration' => $configuration,
|
'configuration' => $configuration,
|
||||||
'pager' => $pager,
|
'pager' => $pager,
|
||||||
|
'sort' => $this->sort,
|
||||||
'filters' => [
|
'filters' => [
|
||||||
'show' => null !== $configuration->getForm('filter'),
|
'show' => null !== $configuration->getForm('filter'),
|
||||||
'isEmpty' => empty($this->filters),
|
'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,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ abstract class Field
|
||||||
'property_builder' => null,
|
'property_builder' => null,
|
||||||
'view' => null,
|
'view' => null,
|
||||||
'raw' => false,
|
'raw' => false,
|
||||||
|
'sort' => null,
|
||||||
'attr' => [],
|
'attr' => [],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -39,6 +40,20 @@ abstract class Field
|
||||||
$resolver->setAllowedTypes('attr', 'array');
|
$resolver->setAllowedTypes('attr', 'array');
|
||||||
$resolver->setAllowedTypes('raw', 'boolean');
|
$resolver->setAllowedTypes('raw', 'boolean');
|
||||||
$resolver->setAllowedTypes('property_builder', ['null', 'callable']);
|
$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;
|
return $resolver;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,12 +51,51 @@
|
||||||
<tr>
|
<tr>
|
||||||
{% for label, config in configuration.fields('index') %}
|
{% for label, config in configuration.fields('index') %}
|
||||||
{% set attr = config.options.attr is defined ? config.options.attr : [] %}
|
{% 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 %}>
|
<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>
|
</th>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<th class="col-2 miw-100 text-right">Actions</th>
|
<th class="col-2 miw-100 text-right">
|
||||||
|
{{ 'Actions'|trans }}
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
Loading…
Reference in a new issue