Add children filter to participant index
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
73089ae654
commit
1a5675634f
|
@ -6,6 +6,7 @@ use App\Form\Models\Form;
|
|||
use App\Form\Models\Participant;
|
||||
use App\Form\Resources\ParticipantResource;
|
||||
use App\Form\Scopes\ParticipantFilterScope;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
@ -14,18 +15,32 @@ class ParticipantIndexAction
|
|||
{
|
||||
use AsAction;
|
||||
|
||||
/**
|
||||
* @return HasMany<Participant>
|
||||
*/
|
||||
protected function getQuery(Form $form, ParticipantFilterScope $filter): HasMany
|
||||
{
|
||||
return $form->participants()->withFilter($filter)->withCount('children')->with('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LengthAwarePaginator<Participant>
|
||||
*/
|
||||
public function handle(Form $form, ParticipantFilterScope $filter): LengthAwarePaginator
|
||||
{
|
||||
return $form->participants()->withFilter($filter)->with('form')->paginate(15);
|
||||
return $this->getQuery($form, $filter)->paginate(15);
|
||||
}
|
||||
|
||||
public function asController(Form $form): AnonymousResourceCollection
|
||||
public function asController(Form $form, ?int $parent = null): AnonymousResourceCollection
|
||||
{
|
||||
$filter = ParticipantFilterScope::fromRequest(request()->input('filter'));
|
||||
return ParticipantResource::collection($this->handle($form, $filter))
|
||||
->additional(['meta' => ParticipantResource::meta($form)]);
|
||||
|
||||
$data = match ($parent) {
|
||||
null => $this->handle($form, $filter),
|
||||
-1 => $this->getQuery($form, $filter)->where('parent_id', null)->get(),
|
||||
default => $this->getQuery($form, $filter)->where('parent_id', $parent)->get(),
|
||||
};
|
||||
|
||||
return ParticipantResource::collection($data)->additional(['meta' => ParticipantResource::meta($form)]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ class ParticipantResource extends JsonResource
|
|||
...$this->getModel()->getFields()->present(),
|
||||
'created_at' => $this->created_at->format('Y-m-d H:i:s'),
|
||||
'created_at_display' => $this->created_at->format('d.m.Y'),
|
||||
'children_count' => $this->children_count,
|
||||
'links' => [
|
||||
'destroy' => route('participant.destroy', ['participant' => $this->getModel()]),
|
||||
]
|
||||
|
|
|
@ -22,7 +22,6 @@ class ParticipantFilterScope extends Filter
|
|||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public function __construct(
|
||||
public ?int $parent = null,
|
||||
public array $data = [],
|
||||
) {
|
||||
}
|
||||
|
@ -45,14 +44,6 @@ class ParticipantFilterScope extends Filter
|
|||
*/
|
||||
public function apply(Builder $query): Builder
|
||||
{
|
||||
if ($this->parent === -1) {
|
||||
$query = $query->whereNull('parent_id');
|
||||
}
|
||||
|
||||
if (!is_null($this->parent) && $this->parent > 0) {
|
||||
$query = $query->where('parent_id', $this->parent);
|
||||
}
|
||||
|
||||
foreach ($this->data as $key => $value) {
|
||||
if ($value === static::$nan) {
|
||||
continue;
|
||||
|
|
|
@ -27,6 +27,7 @@ class ParticipantFactory extends Factory
|
|||
{
|
||||
return [
|
||||
'data' => [],
|
||||
'parent_id' => null,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ Route::group(['middleware' => 'auth:web'], function (): void {
|
|||
Route::delete('/formtemplate/{formtemplate}', FormtemplateDestroyAction::class)->name('formtemplate.destroy');
|
||||
Route::post('/form', FormStoreAction::class)->name('form.store');
|
||||
Route::patch('/form/{form}/meta', FormUpdateMetaAction::class)->name('form.update-meta');
|
||||
Route::get('/form/{form}/participants', ParticipantIndexAction::class)->name('form.participant.index');
|
||||
Route::get('/form/{form}/participants/{parent?}', ParticipantIndexAction::class)->name('form.participant.index');
|
||||
Route::post('/form/{form}/is-dirty', IsDirtyAction::class)->name('form.is-dirty');
|
||||
Route::delete('/participant/{participant}', ParticipantDestroyAction::class)->name('participant.destroy');
|
||||
});
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Tests\Feature\Form;
|
||||
|
||||
use App\Form\Fields\CheckboxField;
|
||||
use App\Form\Fields\TextField;
|
||||
use App\Form\Models\Form;
|
||||
use App\Form\Models\Participant;
|
||||
|
@ -127,30 +126,6 @@ class ParticipantIndexActionTest extends FormTestCase
|
|||
->assertJsonCount(4, 'data');
|
||||
}
|
||||
|
||||
public function testItShowsOnlyRootMembers(): void
|
||||
{
|
||||
$this->login()->loginNami()->withoutExceptionHandling();
|
||||
$form = Form::factory()->create();
|
||||
Participant::factory()->for($form)->count(2)
|
||||
->has(Participant::factory()->count(3)->for($form), 'children')
|
||||
->create();
|
||||
|
||||
$this->callFilter('form.participant.index', ['parent' => -1], ['form' => $form])->assertJsonCount(2, 'data');
|
||||
$this->callFilter('form.participant.index', ['parent' => null], ['form' => $form])->assertJsonCount(8, 'data');
|
||||
}
|
||||
|
||||
public function testItShowsChildrenOfParent(): void
|
||||
{
|
||||
$this->login()->loginNami()->withoutExceptionHandling();
|
||||
$form = Form::factory()->create();
|
||||
$parents = Participant::factory()->for($form)->count(2)
|
||||
->has(Participant::factory()->count(3)->for($form), 'children')
|
||||
->create();
|
||||
|
||||
$this->callFilter('form.participant.index', ['parent' => $parents->get(0)->id], ['form' => $form])->assertJsonCount(3, 'data');
|
||||
$this->callFilter('form.participant.index', ['parent' => $parents->get(1)->id], ['form' => $form])->assertJsonCount(3, 'data');
|
||||
}
|
||||
|
||||
public function testItPresentsNamiField(): void
|
||||
{
|
||||
$this->login()->loginNami()->withoutExceptionHandling();
|
||||
|
@ -191,4 +166,34 @@ class ParticipantIndexActionTest extends FormTestCase
|
|||
->assertJsonPath('meta.columns.1.id', 'created_at')
|
||||
->assertJsonPath('meta.columns.1.display_attribute', 'created_at_display');
|
||||
}
|
||||
|
||||
public function testItShowsOnlyParentParticipantsWhenFilterEnabled(): void
|
||||
{
|
||||
$this->login()->loginNami()->withoutExceptionHandling();
|
||||
$form = Form::factory()->create();
|
||||
$participant = Participant::factory()
|
||||
->has(Participant::factory()->for($form)->count(2), 'children')
|
||||
->for($form)
|
||||
->create();
|
||||
|
||||
$this->callFilter('form.participant.index', [], ['form' => $form])->assertJsonCount(3, 'data');
|
||||
$this->callFilter('form.participant.index', [], ['form' => $form, 'parent' => -1])->assertJsonCount(1, 'data');
|
||||
$this->callFilter('form.participant.index', [], ['form' => $form, 'parent' => $participant->id])->assertJsonCount(2, 'data');
|
||||
}
|
||||
|
||||
public function testItShowsChildrenCount(): void
|
||||
{
|
||||
$this->login()->loginNami()->withoutExceptionHandling();
|
||||
$form = Form::factory()->create();
|
||||
$participant = Participant::factory()
|
||||
->has(Participant::factory()->for($form)->count(2), 'children')
|
||||
->for($form)
|
||||
->create();
|
||||
Participant::factory()->for($form)->create();
|
||||
|
||||
$this->callFilter('form.participant.index', [], ['form' => $form, 'parent' => -1])
|
||||
->assertJsonPath('data.0.children_count', 2)
|
||||
->assertJsonPath('data.1.children_count', 0);
|
||||
$this->callFilter('form.participant.index', [], ['form' => $form, 'parent' => $participant->id])->assertJsonPath('data.0.children_count', 0);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue