From c7b23df01e9197918aa3abb2a124de423fb94191 Mon Sep 17 00:00:00 2001 From: philipp lang Date: Thu, 8 Feb 2024 23:09:51 +0100 Subject: [PATCH] Add participant overview --- app/Form/Actions/ParticipantIndexAction.php | 3 +- app/Form/Fields/CheckboxField.php | 2 - app/Form/Fields/CheckboxesField.php | 2 - app/Form/Fields/DateField.php | 21 ++++++++- app/Form/Fields/DropdownField.php | 2 - app/Form/Fields/Field.php | 18 +++++++- app/Form/Fields/GroupField.php | 19 +++++++- app/Form/Fields/RadioField.php | 2 - app/Form/Fields/TextField.php | 2 - app/Form/Fields/TextareaField.php | 2 - app/Form/Models/Form.php | 10 +++++ app/Form/Resources/ParticipantResource.php | 26 +++++++---- app/Group.php | 7 ++- database/factories/GroupFactory.php | 5 +++ ...2_21_235228_create_formtemplates_table.php | 1 + .../2024_01_12_225811_create_media_table.php | 10 +++++ resources/js/components/ui/Popup.vue | 19 ++++++-- resources/js/views/form/Index.vue | 11 +++++ resources/js/views/form/Participants.vue | 43 +++++++++++++++++++ .../Form/ParticipantIndexActionTest.php | 20 ++++++++- 20 files changed, 192 insertions(+), 33 deletions(-) create mode 100644 resources/js/views/form/Participants.vue diff --git a/app/Form/Actions/ParticipantIndexAction.php b/app/Form/Actions/ParticipantIndexAction.php index 37b6e5a6..f0499130 100644 --- a/app/Form/Actions/ParticipantIndexAction.php +++ b/app/Form/Actions/ParticipantIndexAction.php @@ -6,7 +6,6 @@ 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 @@ -18,7 +17,7 @@ class ParticipantIndexAction return $form->participants()->with('form')->paginate(15); } - public function asController(ActionRequest $request, Form $form): AnonymousResourceCollection + public function asController(Form $form): AnonymousResourceCollection { return ParticipantResource::collection($this->handle($form)) ->additional(['meta' => ParticipantResource::meta($form)]); diff --git a/app/Form/Fields/CheckboxField.php b/app/Form/Fields/CheckboxField.php index 39bae8db..513e3645 100644 --- a/app/Form/Fields/CheckboxField.php +++ b/app/Form/Fields/CheckboxField.php @@ -7,8 +7,6 @@ use Illuminate\Validation\Rule; class CheckboxField extends Field { - public string $name; - public string $key; public bool $required; public string $description; diff --git a/app/Form/Fields/CheckboxesField.php b/app/Form/Fields/CheckboxesField.php index 58c5d486..e8c693d4 100644 --- a/app/Form/Fields/CheckboxesField.php +++ b/app/Form/Fields/CheckboxesField.php @@ -7,8 +7,6 @@ use Illuminate\Validation\Rule; class CheckboxesField extends Field { - public string $name; - public string $key; /** @var array */ public array $options; diff --git a/app/Form/Fields/DateField.php b/app/Form/Fields/DateField.php index f6f91fb1..7a9f691c 100644 --- a/app/Form/Fields/DateField.php +++ b/app/Form/Fields/DateField.php @@ -2,13 +2,13 @@ namespace App\Form\Fields; +use App\Form\Contracts\Displayable; +use Carbon\Carbon; use Faker\Generator; class DateField extends Field { - public string $name; - public string $key; public bool $required; public bool $maxToday; @@ -73,4 +73,21 @@ class DateField extends Field $this->key . '.before_or_equal' => $this->name . ' muss ein Datum vor oder gleich dem ' . now()->format('d.m.Y') . ' sein.', ]; } + + /** + * @param mixed $value + * @return mixed + */ + public function presentValue($value) + { + return [ + $this->key => $value, + $this->key . '_human' => $value ? Carbon::parse($value)->format('d.m.Y') : null, + ]; + } + + public function displayAttribute(): string + { + return $this->key . '_human'; + } } diff --git a/app/Form/Fields/DropdownField.php b/app/Form/Fields/DropdownField.php index 5d4fd525..c2e60aa3 100644 --- a/app/Form/Fields/DropdownField.php +++ b/app/Form/Fields/DropdownField.php @@ -7,8 +7,6 @@ use Illuminate\Validation\Rule; class DropdownField extends Field { - public string $name; - public string $key; public bool $required; /** @var array */ public array $options; diff --git a/app/Form/Fields/Field.php b/app/Form/Fields/Field.php index 3a39e438..bf511259 100644 --- a/app/Form/Fields/Field.php +++ b/app/Form/Fields/Field.php @@ -3,7 +3,6 @@ namespace App\Form\Fields; use Faker\Generator; -use Illuminate\Support\Collection; use Spatie\LaravelData\Data; use Spatie\LaravelData\Attributes\MapInputName; use Spatie\LaravelData\Mappers\SnakeCaseMapper; @@ -12,6 +11,9 @@ use Spatie\LaravelData\Mappers\SnakeCaseMapper; abstract class Field extends Data { + public string $key; + public string $name; + abstract public static function name(): string; /** @return array}> */ @@ -71,6 +73,15 @@ abstract class Field extends Data return static::classFromType($config['type'])::withoutMagicalCreationFrom($config); } + /** + * @param mixed $value + * @return mixed + */ + public function presentValue($value) + { + return [$this->key => $value]; + } + /** * @return array */ @@ -117,4 +128,9 @@ abstract class Field extends Data ], ]; } + + public function displayAttribute(): string + { + return $this->key; + } } diff --git a/app/Form/Fields/GroupField.php b/app/Form/Fields/GroupField.php index cbfc59a1..5006de2d 100644 --- a/app/Form/Fields/GroupField.php +++ b/app/Form/Fields/GroupField.php @@ -9,8 +9,6 @@ use Illuminate\Validation\Rule; class GroupField extends Field { - public string $name; - public string $key; public bool $required; public ?string $parentField = null; public ?int $parentGroup = null; @@ -79,4 +77,21 @@ class GroupField extends Field { return []; } + + /** + * @param mixed $value + * @return mixed + */ + public function presentValue($value) + { + return [ + $this->key => $value, + $this->key . '_name' => Group::find($value)?->display() ?: '' + ]; + } + + public function displayAttribute(): string + { + return $this->key . '_name'; + } } diff --git a/app/Form/Fields/RadioField.php b/app/Form/Fields/RadioField.php index ccf84e57..0ed6fa99 100644 --- a/app/Form/Fields/RadioField.php +++ b/app/Form/Fields/RadioField.php @@ -7,8 +7,6 @@ use Illuminate\Validation\Rule; class RadioField extends Field { - public string $name; - public string $key; public bool $required; /** @var array */ public array $options; diff --git a/app/Form/Fields/TextField.php b/app/Form/Fields/TextField.php index 15a89fbb..67478b60 100644 --- a/app/Form/Fields/TextField.php +++ b/app/Form/Fields/TextField.php @@ -7,8 +7,6 @@ use Faker\Generator; class TextField extends Field { - public string $name; - public string $key; public bool $required; public static function name(): string diff --git a/app/Form/Fields/TextareaField.php b/app/Form/Fields/TextareaField.php index 457d0c0d..df998762 100644 --- a/app/Form/Fields/TextareaField.php +++ b/app/Form/Fields/TextareaField.php @@ -6,8 +6,6 @@ use Faker\Generator; class TextareaField extends Field { - public string $name; - public string $key; public bool $required; public static function name(): string diff --git a/app/Form/Models/Form.php b/app/Form/Models/Form.php index 4ccdcac0..613917a9 100644 --- a/app/Form/Models/Form.php +++ b/app/Form/Models/Form.php @@ -27,6 +27,7 @@ class Form extends Model implements HasMedia public $casts = [ 'config' => 'json', + 'active_columns' => 'json', 'description' => 'json', ]; @@ -133,4 +134,13 @@ class Form extends Model implements HasMedia 'name' => $this->name, ]; } + + public static function booted(): void + { + static::saving(function (self $model) { + if (is_null($model->active_columns)) { + $model->setAttribute('active_columns', $model->getFields()->take(4)->pluck('key')->toArray()); + } + }); + } } diff --git a/app/Form/Resources/ParticipantResource.php b/app/Form/Resources/ParticipantResource.php index 0fe560ca..a0f081d6 100644 --- a/app/Form/Resources/ParticipantResource.php +++ b/app/Form/Resources/ParticipantResource.php @@ -2,6 +2,7 @@ namespace App\Form\Resources; +use App\Form\Fields\Field; use App\Form\Models\Form; use Illuminate\Http\Resources\Json\JsonResource; @@ -15,19 +16,28 @@ class ParticipantResource extends JsonResource */ public function toArray($request) { - return $this->form->getFields()->mapWithKeys(function ($field) { - return [$field['key'] => $this->data[$field['key']]]; - })->toArray(); + $attributes = collect([]); + + foreach ($this->form->getFields() as $field) { + $attributes = $attributes->merge(Field::fromConfig($field)->presentValue($this->data[$field['key']])); + } + + return $attributes; } 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'], - ]) + 'active_columns' => $form->active_columns, + 'columns' => $form->getFields()->map(function ($field) { + $field = Field::fromConfig($field); + return [ + 'name' => $field->name, + 'base_type' => class_basename($field), + 'id' => $field->key, + 'display_attribute' => $field->displayAttribute(), + ]; + }) ]; } } diff --git a/app/Group.php b/app/Group.php index da7952c4..fb5d886e 100644 --- a/app/Group.php +++ b/app/Group.php @@ -55,10 +55,15 @@ class Group extends Model return $result ->reduce( - fn ($before, $group) => $before->concat([['id' => $group->id, 'name' => $prefix . ($group->inner_name ?: $group->name)]]) + fn ($before, $group) => $before->concat([['id' => $group->id, 'name' => $prefix . ($group->display())]]) ->concat($group->children_count > 0 ? self::forSelect($group, $prefix . '-- ') : []), collect([]) ) ->toArray(); } + + public function display(): string + { + return $this->inner_name ?: $this->name; + } } diff --git a/database/factories/GroupFactory.php b/database/factories/GroupFactory.php index cebb7318..f302749a 100644 --- a/database/factories/GroupFactory.php +++ b/database/factories/GroupFactory.php @@ -37,4 +37,9 @@ class GroupFactory extends Factory { return $this->state(['name' => $name]); } + + public function innerName(string $name): self + { + return $this->state(['inner_name' => $name]); + } } diff --git a/database/migrations/2023_12_21_235228_create_formtemplates_table.php b/database/migrations/2023_12_21_235228_create_formtemplates_table.php index 605c86cd..37b27ac6 100644 --- a/database/migrations/2023_12_21_235228_create_formtemplates_table.php +++ b/database/migrations/2023_12_21_235228_create_formtemplates_table.php @@ -33,6 +33,7 @@ return new class extends Migration $table->dateTime('registration_until')->nullable(); $table->text('mail_top')->nullable(); $table->text('mail_bottom')->nullable(); + $table->json('active_columns'); $table->timestamps(); }); } diff --git a/database/migrations/2024_01_12_225811_create_media_table.php b/database/migrations/2024_01_12_225811_create_media_table.php index 32303893..b35f0935 100644 --- a/database/migrations/2024_01_12_225811_create_media_table.php +++ b/database/migrations/2024_01_12_225811_create_media_table.php @@ -29,4 +29,14 @@ return new class extends Migration $table->nullableTimestamps(); }); } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('media'); + } }; diff --git a/resources/js/components/ui/Popup.vue b/resources/js/components/ui/Popup.vue index 0ecc095a..ef40576f 100644 --- a/resources/js/components/ui/Popup.vue +++ b/resources/js/components/ui/Popup.vue @@ -1,6 +1,9 @@