Display CMS Optimierungen 29-05-2026
- Mediathek: Video-Vorschaubilder statt Icons (FFmpeg-Thumbnails + Backfill-Command), Kategorie "Sonstiges" - B2in Media-Picker zeigt alle Medientypen, Typ wird automatisch erkannt; Thumbnail-Preview vor allen Medien-URL-Feldern - B2in Marke/Footer: Footer ein/aus, Logo+Claim frei positionierbar (Ecken) mit Constraints, separate Anzeige-Schalter - Angebote-Modul dynamisch: kein Slide-Typ mehr, einheitliches Detail-Layout mit ein-/ausblendbaren Bloecken, Logo/Brand pro Slide, Streichpreis-Option - Player: leere Module stoppen Endlosschleife, dynamische Layout-Anpassung bei verstecktem Footer/Header - Fix: Script-Ladereihenfolge (Livewire vor Flux), entfernte stale public/flux/flux.js, Modal-Crash beim Aktualisieren behoben Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
9262132325
commit
6c6d683b9a
42 changed files with 2267 additions and 13905 deletions
|
|
@ -115,9 +115,45 @@ test('returns playlist with b2in config', function () {
|
|||
$response->assertSuccessful();
|
||||
$response->assertJsonPath('playlist.0.type', 'b2in');
|
||||
$response->assertJsonPath('playlist.0.settings.theme', 'dark');
|
||||
$response->assertJsonPath('playlist.0.settings.show_footer', true);
|
||||
$response->assertJsonPath('playlist.0.settings.logo_position', 'top-left');
|
||||
$response->assertJsonPath('playlist.0.settings.claim_position', 'top-right');
|
||||
$response->assertJsonPath('playlist.0.items.0.category', 'immobilien');
|
||||
});
|
||||
|
||||
test('b2in config passes through custom brand positions and footer toggle', function () {
|
||||
$version = DisplayVersion::factory()->create([
|
||||
'type' => 'b2in',
|
||||
'settings' => [
|
||||
'show_footer' => false,
|
||||
'logo_position' => 'bottom-right',
|
||||
'claim_position' => 'top-left',
|
||||
],
|
||||
]);
|
||||
DisplayVersionItem::factory()->create([
|
||||
'display_version_id' => $version->id,
|
||||
'item_type' => 'media',
|
||||
'content' => [
|
||||
'category' => 'sonstiges',
|
||||
'media_type' => 'image',
|
||||
'media_url' => '../assets/test.jpg',
|
||||
'headline' => 'H',
|
||||
'subline' => 'S',
|
||||
'duration_seconds' => 10,
|
||||
],
|
||||
]);
|
||||
$display = Display::factory()->create();
|
||||
publishDisplayModules($display, [$version->id]);
|
||||
|
||||
$response = $this->getJson("/api/display/{$display->id}/config");
|
||||
|
||||
$response->assertSuccessful();
|
||||
$response->assertJsonPath('playlist.0.settings.show_footer', false);
|
||||
$response->assertJsonPath('playlist.0.settings.logo_position', 'bottom-right');
|
||||
$response->assertJsonPath('playlist.0.settings.claim_position', 'top-left');
|
||||
$response->assertJsonPath('playlist.0.items.0.category', 'sonstiges');
|
||||
});
|
||||
|
||||
test('returns playlist with offers config', function () {
|
||||
$version = DisplayVersion::factory()->create([
|
||||
'type' => 'offers',
|
||||
|
|
@ -320,38 +356,32 @@ test('module preview returns a single module config', function () {
|
|||
$response->assertJsonPath('playlist.0.items.0.category', 'moebel');
|
||||
});
|
||||
|
||||
test('module preview exposes configurable player chrome settings', function () {
|
||||
test('offers slides carry their own logo and brand chrome', function () {
|
||||
$version = DisplayVersion::factory()->create([
|
||||
'type' => 'offers',
|
||||
'name' => 'Custom Chrome',
|
||||
'settings' => [
|
||||
'logo_url' => '/storage/display-media/logo.svg',
|
||||
'brand_text' => 'Musterstadt',
|
||||
'footer_claim' => 'Beratung im Schauraum',
|
||||
'footer_url' => 'cabinet-bielefeld.de',
|
||||
'qr_default_title' => 'Mehr Infos',
|
||||
'qr_subtitle' => 'Jetzt scannen',
|
||||
],
|
||||
]);
|
||||
DisplayVersionItem::factory()->create([
|
||||
'display_version_id' => $version->id,
|
||||
'item_type' => 'slide',
|
||||
'content' => [
|
||||
'type' => 'intro',
|
||||
'type' => 'detail',
|
||||
'title' => 'Intro',
|
||||
'image_url' => '../assets/intro.jpg',
|
||||
'show_logo' => true,
|
||||
'logo_url' => '/storage/display-media/logo.svg',
|
||||
'brand_text' => 'Musterstadt',
|
||||
'brand_tagline' => 'Beratung im Schauraum',
|
||||
],
|
||||
]);
|
||||
|
||||
$response = $this->getJson("/api/display/module/{$version->id}/preview");
|
||||
|
||||
$response->assertSuccessful();
|
||||
$response->assertJsonPath('playlist.0.settings.logo_url', '/storage/display-media/logo.svg');
|
||||
$response->assertJsonPath('playlist.0.settings.brand_text', 'Musterstadt');
|
||||
$response->assertJsonPath('playlist.0.settings.footer_claim', 'Beratung im Schauraum');
|
||||
$response->assertJsonPath('playlist.0.settings.footer_url', 'cabinet-bielefeld.de');
|
||||
$response->assertJsonPath('playlist.0.settings.qr_default_title', 'Mehr Infos');
|
||||
$response->assertJsonPath('playlist.0.settings.qr_subtitle', 'Jetzt scannen');
|
||||
$response->assertJsonPath('playlist.0.slides.0.show_logo', true);
|
||||
$response->assertJsonPath('playlist.0.slides.0.logo_url', '/storage/display-media/logo.svg');
|
||||
$response->assertJsonPath('playlist.0.slides.0.brand_text', 'Musterstadt');
|
||||
$response->assertJsonPath('playlist.0.slides.0.brand_tagline', 'Beratung im Schauraum');
|
||||
});
|
||||
|
||||
test('module item preview returns only the selected slide', function () {
|
||||
|
|
@ -416,11 +446,28 @@ test('display player keeps previews in a strict 9 by 16 viewport', function () {
|
|||
->toContain('Aktive Live-Displays')
|
||||
->toContain('renderOverview(data.displays || [])')
|
||||
->toContain('translate(${offsetX}px, ${offsetY}px) scale(${scale})')
|
||||
->toContain('this.settings.logo_url')
|
||||
->toContain('this.settings.footer_claim')
|
||||
->toContain('this.settings.footer_url')
|
||||
->toContain('this.settings.header_logo_url')
|
||||
->toContain('this.settings.qr_label');
|
||||
->toContain('this.settings.qr_label')
|
||||
->toContain('this.settings.show_footer !== false')
|
||||
->toContain('this.settings.show_logo !== false')
|
||||
->toContain('this.settings.show_claim !== false')
|
||||
->toContain('this.settings.logo_position')
|
||||
->toContain('this.settings.claim_position')
|
||||
->toContain('b2in-brand-logo pos-')
|
||||
->toContain('b2in-scrim')
|
||||
->toContain('.b2in-layer.no-footer .b2in-text');
|
||||
});
|
||||
|
||||
test('display player stops looping when the playlist has no playable content', function () {
|
||||
$player = file_get_contents(public_path('_cabinet/display/index.html'));
|
||||
|
||||
expect($player)
|
||||
->toContain('versionHasContent(version)')
|
||||
->toContain('showEmptyPlaylist()')
|
||||
->toContain('this.emptyVersionStreak >= this.playlist.length')
|
||||
->toContain('Noch keine Inhalte vorhanden');
|
||||
});
|
||||
|
||||
test('preview player pages are reachable for valid display and module previews', function () {
|
||||
|
|
@ -438,6 +485,20 @@ test('preview player pages are reachable for valid display and module previews',
|
|||
->assertSuccessful();
|
||||
});
|
||||
|
||||
test('preview player is served with a revalidation cache header', function () {
|
||||
$display = Display::factory()->create(['preview_token' => 'fresh-token']);
|
||||
$version = DisplayVersion::factory()->create();
|
||||
|
||||
foreach ([
|
||||
'/preview/fresh-token',
|
||||
"/preview/module/{$version->id}",
|
||||
] as $url) {
|
||||
$response = $this->get($url);
|
||||
$response->assertSuccessful();
|
||||
expect($response->headers->get('Cache-Control'))->toContain('no-cache');
|
||||
}
|
||||
});
|
||||
|
||||
test('existing display config api still works', function () {
|
||||
$response = $this->getJson('/api/display/config');
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue