Add Backend for participant index
This commit is contained in:
parent
48383b25da
commit
590696750b
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Form\Actions;
|
||||
|
||||
use App\Form\Models\Form;
|
||||
use App\Form\Resources\ParticipantResource;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Lorisleiva\Actions\ActionRequest;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class ParticipantIndexAction
|
||||
{
|
||||
use AsAction;
|
||||
|
||||
public function handle(Form $form): LengthAwarePaginator
|
||||
{
|
||||
return $form->participants()->with('form')->paginate(15);
|
||||
}
|
||||
|
||||
public function asController(ActionRequest $request, Form $form): AnonymousResourceCollection
|
||||
{
|
||||
return ParticipantResource::collection($this->handle($form))
|
||||
->additional(['meta' => ParticipantResource::meta($form)]);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ namespace App\Form\Models;
|
|||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Participant extends Model
|
||||
{
|
||||
|
@ -14,4 +15,12 @@ class Participant extends Model
|
|||
public $casts = [
|
||||
'data' => 'json',
|
||||
];
|
||||
|
||||
/**
|
||||
* @return BelongsTo<Form, self>
|
||||
*/
|
||||
public function form(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Form::class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ class FormResource extends JsonResource
|
|||
'config' => $this->config,
|
||||
'participants_count' => $this->participants_count,
|
||||
'links' => [
|
||||
'participant_index' => route('form.participant.index', ['form' => $this->getModel()]),
|
||||
'update' => route('form.update', ['form' => $this->getModel()]),
|
||||
'destroy' => route('form.destroy', ['form' => $this->getModel()]),
|
||||
]
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace App\Form\Resources;
|
||||
|
||||
use App\Form\Models\Form;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class ParticipantResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return $this->form->getFields()->mapWithKeys(function ($field) {
|
||||
return [$field['key'] => $this->data[$field['key']]];
|
||||
})->toArray();
|
||||
}
|
||||
|
||||
public static function meta(Form $form): array
|
||||
{
|
||||
return [
|
||||
'columns' => $form->getFields()->map(fn ($field) => [
|
||||
'name' => $field['name'],
|
||||
'base_type' => class_basename($field['type']),
|
||||
'id' => $field['key'],
|
||||
])
|
||||
];
|
||||
}
|
||||
}
|
|
@ -38,4 +38,12 @@ class ParticipantFactory extends Factory
|
|||
{
|
||||
return $this->state(['config' => ['sections' => array_map(fn ($section) => $section->create(), $sections)]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public function data(array $data): self
|
||||
{
|
||||
return $this->state(['data' => $data]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ use App\Form\Actions\FormtemplateIndexAction;
|
|||
use App\Form\Actions\FormtemplateStoreAction;
|
||||
use App\Form\Actions\FormtemplateUpdateAction;
|
||||
use App\Form\Actions\FormUpdateAction;
|
||||
use App\Form\Actions\ParticipantIndexAction;
|
||||
use App\Initialize\Actions\InitializeAction;
|
||||
use App\Initialize\Actions\InitializeFormAction;
|
||||
use App\Initialize\Actions\NamiGetSearchLayerAction;
|
||||
|
@ -156,4 +157,5 @@ Route::group(['middleware' => 'auth:web'], function (): void {
|
|||
Route::post('/formtemplate', FormtemplateStoreAction::class)->name('formtemplate.store');
|
||||
Route::patch('/formtemplate/{formtemplate}', FormtemplateUpdateAction::class)->name('formtemplate.update');
|
||||
Route::post('/form', FormStoreAction::class)->name('form.store');
|
||||
Route::get('/form/{form}/participants', ParticipantIndexAction::class)->name('form.participant.index');
|
||||
});
|
||||
|
|
|
@ -50,6 +50,7 @@ class FormIndexActionTest extends EndToEndTestCase
|
|||
->assertInertiaPath('data.data.0.to', '2023-06-07')
|
||||
->assertInertiaPath('data.data.0.registration_from', '2023-05-06 04:00:00')
|
||||
->assertInertiaPath('data.data.0.registration_until', '2023-04-01 05:00:00')
|
||||
->assertInertiaPath('data.data.0.links.participant_index', route('form.participant.index', ['form' => $form]))
|
||||
->assertInertiaPath('data.meta.links.store', route('form.store'))
|
||||
->assertInertiaPath('data.meta.links.formtemplate_index', route('formtemplate.index'))
|
||||
->assertInertiaPath('data.meta.templates.0.name', 'tname')
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Form;
|
||||
|
||||
use App\Form\Fields\CheckboxesField;
|
||||
use App\Form\Fields\DropdownField;
|
||||
use App\Form\Fields\TextField;
|
||||
use App\Form\Models\Form;
|
||||
use App\Form\Models\Participant;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ParticipantIndexActionTest extends TestCase
|
||||
{
|
||||
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function testItShowsParticipantsAndColumns(): void
|
||||
{
|
||||
$this->login()->loginNami()->withoutExceptionHandling();
|
||||
$form = Form::factory()
|
||||
->has(Participant::factory()->data(['vorname' => 'Max', 'select' => 'A', 'stufe' => 'Pfadfinder']))
|
||||
->sections([
|
||||
FormtemplateSectionRequest::new()->fields([
|
||||
FormtemplateFieldRequest::type(TextField::class)->name('Vorname')->key('vorname'),
|
||||
FormtemplateFieldRequest::type(CheckboxesField::class)->key('select')->options(['A', 'B', 'C']),
|
||||
FormtemplateFieldRequest::type(DropdownField::class)->key('stufe')->options(['Wölfling', 'Jungpfadfinder', 'Pfadfinder']),
|
||||
]),
|
||||
])
|
||||
->create();
|
||||
|
||||
$this->callFilter('form.participant.index', [], ['form' => $form])
|
||||
->assertOk()
|
||||
->assertJsonPath('data.0.vorname', 'Max')
|
||||
->assertJsonPath('data.0.stufe', 'Pfadfinder')
|
||||
->assertJsonPath('meta.columns.0.name', 'Vorname')
|
||||
->assertJsonPath('meta.columns.0.base_type', class_basename(TextField::class))
|
||||
->assertJsonPath('meta.columns.0.id', 'vorname');
|
||||
}
|
||||
}
|
|
@ -8,19 +8,22 @@ trait MakesHttpCalls
|
|||
{
|
||||
/**
|
||||
* @param array<string, mixed> $filter
|
||||
* @param array<string, mixed> $routeParams
|
||||
*/
|
||||
public function callFilter(string $routeName, array $filter): TestResponse
|
||||
public function callFilter(string $routeName, array $filter, array $routeParams = []): TestResponse
|
||||
{
|
||||
return $this->call('GET', $this->filterUrl($routeName, $filter));
|
||||
return $this->call('GET', $this->filterUrl($routeName, $filter, $routeParams));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $filter
|
||||
* @param array<string, mixed> $routeParams
|
||||
*/
|
||||
public function filterUrl(string $routeName, array $filter): string
|
||||
public function filterUrl(string $routeName, array $filter, array $routeParams = []): string
|
||||
{
|
||||
$params = [
|
||||
'filter' => $this->filterString($filter),
|
||||
...$routeParams
|
||||
];
|
||||
|
||||
return route($routeName, $params);
|
||||
|
|
Loading…
Reference in New Issue