Add sorting to participant list
continuous-integration/drone/push Build was killed
Details
continuous-integration/drone/push Build was killed
Details
This commit is contained in:
parent
70e085a49e
commit
a3ecfa756d
|
@ -20,7 +20,7 @@ class UpdateParticipantSearchIndexAction
|
||||||
[
|
[
|
||||||
'filterableAttributes' => [...$form->getFields()->filterables()->getKeys(), 'parent-id'],
|
'filterableAttributes' => [...$form->getFields()->filterables()->getKeys(), 'parent-id'],
|
||||||
'searchableAttributes' => $form->getFields()->searchables()->getKeys(),
|
'searchableAttributes' => $form->getFields()->searchables()->getKeys(),
|
||||||
'sortableAttributes' => [],
|
'sortableAttributes' => $form->getFields()->sortables()->getKeys(),
|
||||||
'displayedAttributes' => [...$form->getFields()->filterables()->getKeys(), ...$form->getFields()->searchables()->getKeys(), 'id'],
|
'displayedAttributes' => [...$form->getFields()->filterables()->getKeys(), ...$form->getFields()->searchables()->getKeys(), 'id'],
|
||||||
'pagination' => [
|
'pagination' => [
|
||||||
'maxTotalHits' => 1000000,
|
'maxTotalHits' => 1000000,
|
||||||
|
|
|
@ -124,6 +124,11 @@ class FieldCollection extends Collection
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function sortables(): self
|
||||||
|
{
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function filterables(): self
|
public function filterables(): self
|
||||||
{
|
{
|
||||||
return $this->filter(fn ($field) => $field instanceof Filterable);
|
return $this->filter(fn ($field) => $field instanceof Filterable);
|
||||||
|
|
|
@ -8,6 +8,7 @@ use App\Form\Data\FieldCollection;
|
||||||
use App\Form\Data\FormConfigData;
|
use App\Form\Data\FormConfigData;
|
||||||
use App\Lib\Editor\Condition;
|
use App\Lib\Editor\Condition;
|
||||||
use App\Lib\Editor\EditorData;
|
use App\Lib\Editor\EditorData;
|
||||||
|
use App\Lib\Sorting;
|
||||||
use Cviebrock\EloquentSluggable\Sluggable;
|
use Cviebrock\EloquentSluggable\Sluggable;
|
||||||
use Database\Factories\Form\Models\FormFactory;
|
use Database\Factories\Form\Models\FormFactory;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
@ -182,4 +183,9 @@ class Form extends Model implements HasMedia
|
||||||
{
|
{
|
||||||
return config('scout.prefix') . 'forms_' . $this->id . '_participants';
|
return config('scout.prefix') . 'forms_' . $this->id . '_participants';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function defaultSorting(): Sorting
|
||||||
|
{
|
||||||
|
return Sorting::by(data_get($this->meta, 'active_columns.0'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ namespace App\Form\Scopes;
|
||||||
|
|
||||||
use App\Form\Models\Form;
|
use App\Form\Models\Form;
|
||||||
use App\Form\Models\Participant;
|
use App\Form\Models\Participant;
|
||||||
use App\Lib\Filter;
|
|
||||||
use App\Lib\ScoutFilter;
|
use App\Lib\ScoutFilter;
|
||||||
|
use App\Lib\Sorting;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use Laravel\Scout\Builder;
|
use Laravel\Scout\Builder;
|
||||||
use Spatie\LaravelData\Attributes\MapInputName;
|
use Spatie\LaravelData\Attributes\MapInputName;
|
||||||
|
@ -31,7 +31,8 @@ class ParticipantFilterScope extends ScoutFilter
|
||||||
public array $data = [],
|
public array $data = [],
|
||||||
public string $search = '',
|
public string $search = '',
|
||||||
public array $options = [],
|
public array $options = [],
|
||||||
public ?int $parent = null
|
public ?int $parent = null,
|
||||||
|
public ?Sorting $sort = null
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +60,8 @@ class ParticipantFilterScope extends ScoutFilter
|
||||||
|
|
||||||
$options['filter'] = $filter->map(fn ($expression) => "($expression)")->implode(' AND ');
|
$options['filter'] = $filter->map(fn ($expression) => "($expression)")->implode(' AND ');
|
||||||
|
|
||||||
|
$options['sort'] = $this->sort->toMeilisearch();
|
||||||
|
|
||||||
return $engine->search($query, [...$this->options, ...$options]);
|
return $engine->search($query, [...$this->options, ...$options]);
|
||||||
})->within($this->form->participantsSearchableAs());
|
})->within($this->form->participantsSearchableAs());
|
||||||
}
|
}
|
||||||
|
@ -67,6 +70,10 @@ class ParticipantFilterScope extends ScoutFilter
|
||||||
{
|
{
|
||||||
$this->form = $form;
|
$this->form = $form;
|
||||||
|
|
||||||
|
if (is_null($this->sort)) {
|
||||||
|
$this->sort = $this->form->defaultSorting();
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($form->getFields() as $field) {
|
foreach ($form->getFields() as $field) {
|
||||||
if (!Arr::has($this->data, $field->key)) {
|
if (!Arr::has($this->data, $field->key)) {
|
||||||
data_set($this->data, $field->key, static::$nan);
|
data_set($this->data, $field->key, static::$nan);
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Lib;
|
||||||
|
|
||||||
|
use Spatie\LaravelData\Data;
|
||||||
|
|
||||||
|
class Sorting extends Data
|
||||||
|
{
|
||||||
|
public static function by(string $by): self
|
||||||
|
{
|
||||||
|
return static::factory()->withoutMagicalCreation()->from(['by' => $by]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct(public string $by, public bool $direction = false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
|
public function toMeilisearch(): array
|
||||||
|
{
|
||||||
|
return [$this->by . ':' . ($this->direction ? 'desc' : 'asc')];
|
||||||
|
}
|
||||||
|
}
|
|
@ -239,3 +239,40 @@ it('testItShowsPreventionState', function () {
|
||||||
->assertJsonPath('data.0.prevention_items.0.value', false)
|
->assertJsonPath('data.0.prevention_items.0.value', false)
|
||||||
->assertJsonPath('data.0.prevention_items.0.tooltip', 'erweitertes Führungszeugnis nicht vorhanden');
|
->assertJsonPath('data.0.prevention_items.0.tooltip', 'erweitertes Führungszeugnis nicht vorhanden');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('test it orders participants by value', function (array $values, array $sorting, array $expected) {
|
||||||
|
list($key, $direction) = $sorting;
|
||||||
|
$this->login()->loginNami()->withoutExceptionHandling();
|
||||||
|
$form = Form::factory()
|
||||||
|
->fields([
|
||||||
|
$this->textField('vorname')->name('Vorname'),
|
||||||
|
$this->checkboxesField('select')->options(['Wölflinge', 'Pfadfinder']),
|
||||||
|
]);
|
||||||
|
foreach ($values as $value) {
|
||||||
|
$form = $form->has(Participant::factory()->data(['vorname' => 'Max', 'select' => 'Pfadfinder', $key => $value]));
|
||||||
|
}
|
||||||
|
$form = $form->create();
|
||||||
|
|
||||||
|
sleep(2);
|
||||||
|
$response = $this->callFilter('form.participant.index', ['sort' => ['by' => $key, 'direction' => $direction]], ['form' => $form]);
|
||||||
|
|
||||||
|
foreach ($expected as $index => $value) {
|
||||||
|
$response->assertJsonPath("data.{$index}.{$key}", $value);
|
||||||
|
}
|
||||||
|
})->with([
|
||||||
|
[
|
||||||
|
['Anna', 'Sarah', 'Ben'],
|
||||||
|
['vorname', false],
|
||||||
|
['Anna', 'Ben', 'Sarah'],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
['Anna', 'Sarah', 'Ben'],
|
||||||
|
['vorname', true],
|
||||||
|
['Sarah', 'Ben', 'Anna'],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
['Wölflinge', 'Pfadfinder'],
|
||||||
|
['select', false],
|
||||||
|
['Pfadfinder', 'Wölflinge'],
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
Loading…
Reference in New Issue