From 6c2da9bdac7bc3db45c3ad3983b2499d1d774162 Mon Sep 17 00:00:00 2001 From: Kevin Adametz Date: Thu, 18 Jun 2026 08:24:40 +0000 Subject: [PATCH] Display-Module in der Modulliste duplizieren. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ermöglicht das Kopieren inklusive aller Inhalte und Einstellungen mit fortlaufender Benennung als „Kopie N - …“. Co-authored-by: Cursor --- app/Livewire/Admin/Cms/DisplayVersionList.php | 49 +++++++++++++++ .../admin/cms/display-version-list.blade.php | 8 +++ tests/Feature/DisplayVersionTest.php | 59 +++++++++++++++++++ 3 files changed, 116 insertions(+) diff --git a/app/Livewire/Admin/Cms/DisplayVersionList.php b/app/Livewire/Admin/Cms/DisplayVersionList.php index 80dd21ec..69189a46 100644 --- a/app/Livewire/Admin/Cms/DisplayVersionList.php +++ b/app/Livewire/Admin/Cms/DisplayVersionList.php @@ -80,6 +80,55 @@ class DisplayVersionList extends Component $version->update(['is_active' => ! $version->is_active]); } + public function copyVersion(int $id): void + { + $source = DisplayVersion::query()->with('items')->findOrFail($id); + + $copy = DB::transaction(function () use ($source) { + $copy = DisplayVersion::create([ + 'name' => $this->copyNameFor($source->name), + 'type' => $source->type, + 'settings' => $source->settings ?? [], + 'is_active' => $source->is_active, + ]); + + foreach ($source->items as $item) { + $copy->items()->create([ + 'item_type' => $item->item_type, + 'content' => $item->content, + 'sort_order' => $item->sort_order, + 'is_active' => $item->is_active, + ]); + } + + return $copy; + }); + + session()->flash('success', 'Modul "'.$source->name.'" wurde als "'.$copy->name.'" kopiert!'); + } + + private function copyNameFor(string $sourceName): string + { + $baseName = preg_match('/^Kopie \d+ - (.+)$/', $sourceName, $matches) === 1 + ? $matches[1] + : $sourceName; + + $maxCopyNumber = 0; + + DisplayVersion::query() + ->where('name', 'like', 'Kopie % - '.$baseName) + ->pluck('name') + ->each(function (string $name) use ($baseName, &$maxCopyNumber): void { + if (preg_match('/^Kopie (\d+) - '.preg_quote($baseName, '/').'$/', $name, $matches) !== 1) { + return; + } + + $maxCopyNumber = max($maxCopyNumber, (int) $matches[1]); + }); + + return 'Kopie '.($maxCopyNumber + 1).' - '.$baseName; + } + /** * @return array */ diff --git a/resources/views/livewire/admin/cms/display-version-list.blade.php b/resources/views/livewire/admin/cms/display-version-list.blade.php index 4caecae3..258d6432 100644 --- a/resources/views/livewire/admin/cms/display-version-list.blade.php +++ b/resources/views/livewire/admin/cms/display-version-list.blade.php @@ -79,6 +79,14 @@ icon="pencil"> + + + fresh()->is_active)->toBeFalse(); }); +test('can copy a display version with all items and settings', function () { + $user = User::factory()->create(); + $source = DisplayVersion::factory()->create([ + 'name' => 'B2In Immobilien Dark', + 'type' => DisplayVersionType::B2in, + 'settings' => ['theme' => 'dark', 'show_footer' => false], + 'is_active' => true, + ]); + DisplayVersionItem::factory()->create([ + 'display_version_id' => $source->id, + 'item_type' => 'media', + 'content' => ['headline' => 'Test Headline'], + 'sort_order' => 0, + ]); + DisplayVersionItem::factory()->create([ + 'display_version_id' => $source->id, + 'item_type' => 'media', + 'content' => ['headline' => 'Zweites Medium'], + 'sort_order' => 1, + ]); + + Livewire::actingAs($user) + ->test(DisplayVersionList::class) + ->call('copyVersion', $source->id); + + $copy = DisplayVersion::query()->where('name', 'Kopie 1 - B2In Immobilien Dark')->first(); + + expect($copy)->not->toBeNull() + ->and($copy->type)->toBe(DisplayVersionType::B2in) + ->and($copy->settings)->toBe(['theme' => 'dark', 'show_footer' => false]) + ->and($copy->is_active)->toBeTrue() + ->and($copy->items)->toHaveCount(2) + ->and($copy->items->pluck('content.headline')->all())->toBe(['Test Headline', 'Zweites Medium']); +}); + +test('copying a display version increments the copy number', function () { + $user = User::factory()->create(); + $source = DisplayVersion::factory()->create(['name' => 'Schaufenster Video']); + + Livewire::actingAs($user) + ->test(DisplayVersionList::class) + ->call('copyVersion', $source->id) + ->call('copyVersion', $source->id); + + expect(DisplayVersion::where('name', 'Kopie 1 - Schaufenster Video')->exists())->toBeTrue() + ->and(DisplayVersion::where('name', 'Kopie 2 - Schaufenster Video')->exists())->toBeTrue(); +}); + +test('copying an existing copy keeps the original base name in the title', function () { + $user = User::factory()->create(); + $copy = DisplayVersion::factory()->create(['name' => 'Kopie 1 - Angebote Schauraum']); + + Livewire::actingAs($user) + ->test(DisplayVersionList::class) + ->call('copyVersion', $copy->id); + + expect(DisplayVersion::where('name', 'Kopie 2 - Angebote Schauraum')->exists())->toBeTrue(); +}); + // ======================================== // DisplayVersionEditor // ========================================