feat: registration form field display_width and option descriptions
Add configurable column widths (full/half) and optional descriptions for radio/select/checkbox options on registration form fields. - Migration adds display_width column to both tables - FieldDisplayWidth enum with smart defaults per field type - normalized_options accessor for backwards-compatible option format - Portal form renderer uses display_width for VRow/VCol grid layout - Radio/select/checkbox options render with descriptions - Admin field editor supports display_width toggle and description input - System templates updated with appropriate widths and descriptions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -360,4 +360,136 @@ class RegistrationFormFieldTest extends TestCase
|
||||
|
||||
$response->assertUnauthorized();
|
||||
}
|
||||
|
||||
public function test_store_field_with_display_width(): void
|
||||
{
|
||||
Sanctum::actingAs($this->orgAdmin);
|
||||
|
||||
$response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields", [
|
||||
'label' => 'Noodcontact naam',
|
||||
'field_type' => 'text',
|
||||
'display_width' => 'half',
|
||||
]);
|
||||
|
||||
$response->assertCreated()
|
||||
->assertJsonPath('data.display_width', 'half');
|
||||
|
||||
$this->assertDatabaseHas('registration_form_fields', [
|
||||
'event_id' => $this->event->id,
|
||||
'slug' => 'noodcontact-naam',
|
||||
'display_width' => 'half',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_store_field_defaults_display_width_by_type(): void
|
||||
{
|
||||
Sanctum::actingAs($this->orgAdmin);
|
||||
|
||||
// Text fields default to 'half'
|
||||
$response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields", [
|
||||
'label' => 'Korte tekst',
|
||||
'field_type' => 'text',
|
||||
]);
|
||||
|
||||
$response->assertCreated()
|
||||
->assertJsonPath('data.display_width', 'half');
|
||||
|
||||
// Textarea fields default to 'full'
|
||||
$response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields", [
|
||||
'label' => 'Opmerkingen',
|
||||
'field_type' => 'textarea',
|
||||
]);
|
||||
|
||||
$response->assertCreated()
|
||||
->assertJsonPath('data.display_width', 'full');
|
||||
}
|
||||
|
||||
public function test_update_field_display_width(): void
|
||||
{
|
||||
$field = RegistrationFormField::factory()->create([
|
||||
'event_id' => $this->event->id,
|
||||
'display_width' => 'full',
|
||||
]);
|
||||
|
||||
Sanctum::actingAs($this->orgAdmin);
|
||||
|
||||
$response = $this->putJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields/{$field->id}", [
|
||||
'display_width' => 'half',
|
||||
]);
|
||||
|
||||
$response->assertOk()
|
||||
->assertJsonPath('data.display_width', 'half');
|
||||
}
|
||||
|
||||
public function test_store_field_with_option_descriptions(): void
|
||||
{
|
||||
Sanctum::actingAs($this->orgAdmin);
|
||||
|
||||
$response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields", [
|
||||
'label' => 'Vergoeding',
|
||||
'field_type' => 'radio',
|
||||
'options' => [
|
||||
['label' => 'Pro Deo', 'description' => 'Geen vergoeding'],
|
||||
['label' => 'Entreeticket', 'description' => 'Gratis ticket'],
|
||||
],
|
||||
]);
|
||||
|
||||
$response->assertCreated()
|
||||
->assertJsonPath('data.normalized_options.0.label', 'Pro Deo')
|
||||
->assertJsonPath('data.normalized_options.0.description', 'Geen vergoeding')
|
||||
->assertJsonPath('data.normalized_options.1.label', 'Entreeticket')
|
||||
->assertJsonPath('data.normalized_options.1.description', 'Gratis ticket');
|
||||
}
|
||||
|
||||
public function test_options_backwards_compatible_with_string_array(): void
|
||||
{
|
||||
Sanctum::actingAs($this->orgAdmin);
|
||||
|
||||
$response = $this->postJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields", [
|
||||
'label' => 'Shirtmaat',
|
||||
'field_type' => 'select',
|
||||
'options' => ['XS', 'S', 'M', 'L'],
|
||||
]);
|
||||
|
||||
$response->assertCreated()
|
||||
->assertJsonPath('data.normalized_options.0.label', 'XS')
|
||||
->assertJsonPath('data.normalized_options.0.description', null)
|
||||
->assertJsonPath('data.normalized_options.3.label', 'L');
|
||||
}
|
||||
|
||||
public function test_normalized_options_converts_strings_to_objects(): void
|
||||
{
|
||||
$field = RegistrationFormField::factory()->selectField()->create([
|
||||
'event_id' => $this->event->id,
|
||||
]);
|
||||
|
||||
$this->assertNotNull($field->normalized_options);
|
||||
$this->assertIsArray($field->normalized_options);
|
||||
|
||||
// Each option should be an array with label and description keys
|
||||
foreach ($field->normalized_options as $option) {
|
||||
$this->assertArrayHasKey('label', $option);
|
||||
$this->assertArrayHasKey('description', $option);
|
||||
$this->assertIsString($option['label']);
|
||||
}
|
||||
}
|
||||
|
||||
public function test_index_returns_display_width_and_normalized_options(): void
|
||||
{
|
||||
RegistrationFormField::factory()->radioField()->create([
|
||||
'event_id' => $this->event->id,
|
||||
'sort_order' => 0,
|
||||
]);
|
||||
|
||||
Sanctum::actingAs($this->orgAdmin);
|
||||
|
||||
$response = $this->getJson("/api/v1/organisations/{$this->organisation->id}/events/{$this->event->id}/registration-fields");
|
||||
|
||||
$response->assertOk();
|
||||
$field = $response->json('data.0');
|
||||
$this->assertArrayHasKey('display_width', $field);
|
||||
$this->assertArrayHasKey('normalized_options', $field);
|
||||
$this->assertEquals('full', $field['display_width']);
|
||||
$this->assertNotNull($field['normalized_options']);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user