feat(controller): pass agenda items to edit page

This commit is contained in:
Thorsten Bus 2026-03-29 11:48:28 +02:00
parent 2d70026a20
commit 0b671956d6
3 changed files with 245 additions and 5 deletions

View file

@ -3,8 +3,10 @@
namespace App\Http\Controllers;
use App\Models\Service;
use App\Models\Setting;
use App\Models\Slide;
use App\Models\Song;
use App\Services\AgendaMatcherService;
use App\Services\ProBundleExportService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
@ -94,6 +96,11 @@ public function edit(Service $service): Response
'serviceSongs.song.arrangements.arrangementGroups.group',
'serviceSongs.arrangement',
'slides',
'agendaItems' => fn ($q) => $q->orderBy('sort_order'),
'agendaItems.slides',
'agendaItems.serviceSong.song.groups.slides',
'agendaItems.serviceSong.song.arrangements.arrangementGroups.group',
'agendaItems.serviceSong.arrangement.arrangementGroups.group',
]);
$songsCatalog = Song::query()
@ -148,6 +155,41 @@ public function edit(Service $service): Response
->orderBy('date')
->first(['id', 'title', 'date']);
// Load agenda settings
$agendaSettings = [
'start_title' => Setting::get('agenda_start_title'),
'end_title' => Setting::get('agenda_end_title'),
'announcement_position' => Setting::get('agenda_announcement_position'),
'sermon_matching' => Setting::get('agenda_sermon_matching'),
];
// Filter agenda items (exclude before-event, apply boundary filtering)
$matcher = app(AgendaMatcherService::class);
$agendaItemsArray = $service->agendaItems
->filter(fn ($i) => ! $i->is_before_event)
->values()
->all();
$filteredItems = $matcher->filterBetween(
$agendaItemsArray,
$agendaSettings['start_title'],
$agendaSettings['end_title']
);
// Add computed flags to each agenda item
$announcementPatterns = $agendaSettings['announcement_position'];
$sermonPatterns = $agendaSettings['sermon_matching'];
$agendaItemsMapped = array_map(function ($item) use ($matcher, $announcementPatterns, $sermonPatterns) {
$arr = $item->toArray();
$arr['is_announcement_position'] = $announcementPatterns
? $matcher->matchesAny($item->title, array_map('trim', explode(',', $announcementPatterns)))
: false;
$arr['is_sermon'] = $sermonPatterns
? $matcher->matchesAny($item->title, array_map('trim', explode(',', $sermonPatterns)))
: false;
return $arr;
}, $filteredItems);
return Inertia::render('Services/Edit', [
'service' => [
'id' => $service->id,
@ -210,6 +252,8 @@ public function edit(Service $service): Response
'moderationSlides' => $moderationSlides,
'sermonSlides' => $sermonSlides,
'songsCatalog' => $songsCatalog,
'agendaItems' => $agendaItemsMapped,
'agendaSettings' => $agendaSettings,
'prevService' => $prevService ? [
'id' => $prevService->id,
'title' => $prevService->title,

View file

@ -3,7 +3,9 @@
namespace Tests\Feature;
use App\Models\Service;
use App\Models\ServiceAgendaItem;
use App\Models\ServiceSong;
use App\Models\Setting;
use App\Models\Slide;
use App\Models\Song;
use App\Models\SongArrangement;
@ -351,4 +353,198 @@ public function test_services_index_zeigt_vergangene_services_mit_archived_param
->where('archived', true)
);
}
public function test_edit_seite_liefert_leere_agenda_items_und_settings(): void
{
Carbon::setTestNow('2026-03-01 10:00:00');
$this->withoutVite();
$user = User::factory()->create();
$service = Service::factory()->create([
'date' => Carbon::today()->addDays(7),
]);
$response = $this->actingAs($user)->get(route('services.edit', $service));
$response->assertOk();
$response->assertInertia(
fn ($page) => $page
->component('Services/Edit')
->has('agendaItems', 0)
->has('agendaSettings')
->where('agendaSettings.start_title', null)
->where('agendaSettings.end_title', null)
->where('agendaSettings.announcement_position', null)
->where('agendaSettings.sermon_matching', null)
);
}
public function test_edit_seite_liefert_agenda_items_mit_computed_flags(): void
{
Carbon::setTestNow('2026-03-01 10:00:00');
$this->withoutVite();
$user = User::factory()->create();
$service = Service::factory()->create([
'date' => Carbon::today()->addDays(7),
]);
Setting::set('agenda_announcement_position', 'Hinweis*,Information*');
Setting::set('agenda_sermon_matching', 'Predigt*');
ServiceAgendaItem::factory()->create([
'service_id' => $service->id,
'title' => 'Lobpreis',
'sort_order' => 1,
'is_before_event' => false,
]);
ServiceAgendaItem::factory()->create([
'service_id' => $service->id,
'title' => 'Hinweise und Infos',
'sort_order' => 2,
'is_before_event' => false,
]);
ServiceAgendaItem::factory()->create([
'service_id' => $service->id,
'title' => 'Predigt: Thema',
'sort_order' => 3,
'is_before_event' => false,
]);
$response = $this->actingAs($user)->get(route('services.edit', $service));
$response->assertOk();
$response->assertInertia(
fn ($page) => $page
->component('Services/Edit')
->has('agendaItems', 3)
->where('agendaItems.0.title', 'Lobpreis')
->where('agendaItems.0.is_announcement_position', false)
->where('agendaItems.0.is_sermon', false)
->where('agendaItems.1.title', 'Hinweise und Infos')
->where('agendaItems.1.is_announcement_position', true)
->where('agendaItems.1.is_sermon', false)
->where('agendaItems.2.title', 'Predigt: Thema')
->where('agendaItems.2.is_announcement_position', false)
->where('agendaItems.2.is_sermon', true)
);
}
public function test_edit_seite_filtert_agenda_items_mit_start_end_grenzen(): void
{
Carbon::setTestNow('2026-03-01 10:00:00');
$this->withoutVite();
$user = User::factory()->create();
$service = Service::factory()->create([
'date' => Carbon::today()->addDays(7),
]);
Setting::set('agenda_start_title', 'Beginn*');
Setting::set('agenda_end_title', 'Segen*');
ServiceAgendaItem::factory()->create([
'service_id' => $service->id,
'title' => 'Beginn Gottesdienst',
'sort_order' => 1,
'is_before_event' => false,
]);
ServiceAgendaItem::factory()->create([
'service_id' => $service->id,
'title' => 'Lobpreis',
'sort_order' => 2,
'is_before_event' => false,
]);
ServiceAgendaItem::factory()->create([
'service_id' => $service->id,
'title' => 'Predigt',
'sort_order' => 3,
'is_before_event' => false,
]);
ServiceAgendaItem::factory()->create([
'service_id' => $service->id,
'title' => 'Segen und Sendung',
'sort_order' => 4,
'is_before_event' => false,
]);
$response = $this->actingAs($user)->get(route('services.edit', $service));
$response->assertOk();
$response->assertInertia(
fn ($page) => $page
->component('Services/Edit')
->has('agendaItems', 2)
->where('agendaItems.0.title', 'Lobpreis')
->where('agendaItems.1.title', 'Predigt')
);
}
public function test_edit_seite_schliesst_before_event_items_aus(): void
{
Carbon::setTestNow('2026-03-01 10:00:00');
$this->withoutVite();
$user = User::factory()->create();
$service = Service::factory()->create([
'date' => Carbon::today()->addDays(7),
]);
ServiceAgendaItem::factory()->create([
'service_id' => $service->id,
'title' => 'Technik Check',
'sort_order' => 1,
'is_before_event' => true,
]);
ServiceAgendaItem::factory()->create([
'service_id' => $service->id,
'title' => 'Lobpreis',
'sort_order' => 2,
'is_before_event' => false,
]);
$response = $this->actingAs($user)->get(route('services.edit', $service));
$response->assertOk();
$response->assertInertia(
fn ($page) => $page
->component('Services/Edit')
->has('agendaItems', 1)
->where('agendaItems.0.title', 'Lobpreis')
);
}
public function test_edit_seite_liefert_agenda_settings_mit_allen_vier_keys(): void
{
Carbon::setTestNow('2026-03-01 10:00:00');
$this->withoutVite();
$user = User::factory()->create();
$service = Service::factory()->create([
'date' => Carbon::today()->addDays(7),
]);
Setting::set('agenda_start_title', 'Beginn*');
Setting::set('agenda_end_title', 'Segen*');
Setting::set('agenda_announcement_position', 'Hinweis*');
Setting::set('agenda_sermon_matching', 'Predigt*');
$response = $this->actingAs($user)->get(route('services.edit', $service));
$response->assertOk();
$response->assertInertia(
fn ($page) => $page
->component('Services/Edit')
->where('agendaSettings.start_title', 'Beginn*')
->where('agendaSettings.end_title', 'Segen*')
->where('agendaSettings.announcement_position', 'Hinweis*')
->where('agendaSettings.sermon_matching', 'Predigt*')
);
}
}

View file

@ -14,11 +14,11 @@
$response->assertInertia(
fn ($page) => $page
->component('Settings')
->has('settings.agenda_start_title')
->has('settings.agenda_end_title')
->has('settings.agenda_announcement_position')
->has('settings.agenda_sermon_matching')
->component('Settings')
->has('settings.agenda_start_title')
->has('settings.agenda_end_title')
->has('settings.agenda_announcement_position')
->has('settings.agenda_sermon_matching')
);
});