diff --git a/app/Livewire/Buckets.php b/app/Livewire/Buckets.php
index 19f1614..5e5f47b 100644
--- a/app/Livewire/Buckets.php
+++ b/app/Livewire/Buckets.php
@@ -33,12 +33,25 @@ public function buckets()
return Bucket::forCredential($credential, $activeRegion)->all();
}
+ #[Computed]
+ public function activeBucket()
+ {
+ return Settings::get('active-bucket');
+ }
+
#[On('region-switched')]
public function refreshBuckets(): void
{
unset($this->buckets);
}
+ public function selectBucket(string $bucketName): void
+ {
+ Settings::set('active-bucket', $bucketName);
+
+ $this->dispatch('bucket-selected', bucketName: $bucketName);
+ }
+
public function placeholder()
{
return <<<'HTML'
diff --git a/resources/views/livewire/buckets.blade.php b/resources/views/livewire/buckets.blade.php
index ef2234d..0046a6b 100644
--- a/resources/views/livewire/buckets.blade.php
+++ b/resources/views/livewire/buckets.blade.php
@@ -1,7 +1,26 @@
@forelse ($this->buckets as $bucket)
- -
+
- activeBucket === $bucket['name'], 'data-active') }}
+ role="button"
+ wire:click="selectBucket({{ json_encode($bucket['name']) }})"
+ class="hover:bg-accent data-active:bg-accent flex cursor-pointer items-center justify-between rounded-md p-2 transition-colors">
{{ $bucket['name'] }}
+
+ @if ($this->activeBucket === $bucket['name'])
+
+ @endif
@if (! $loop->last)
diff --git a/tests/Feature/Livewire/BucketsTest.php b/tests/Feature/Livewire/BucketsTest.php
new file mode 100644
index 0000000..a3994af
--- /dev/null
+++ b/tests/Feature/Livewire/BucketsTest.php
@@ -0,0 +1,95 @@
+assertStatus(200);
+ });
+
+ it('displays empty state when no buckets are available', function () {
+ Livewire::test(Buckets::class)
+ ->assertSee('No S3 buckets found.');
+ });
+
+ it('can select a bucket', function () {
+ $bucketName = 'test-bucket';
+
+ Livewire::test(Buckets::class)
+ ->call('selectBucket', $bucketName)
+ ->assertDispatched('bucket-selected', bucketName: $bucketName);
+
+ expect(Settings::get('active-bucket'))->toBe($bucketName);
+ });
+
+ it('stores selected bucket in settings', function () {
+ $bucketName = 'my-s3-bucket';
+
+ Livewire::test(Buckets::class)
+ ->call('selectBucket', $bucketName);
+
+ expect(Settings::get('active-bucket'))->toBe($bucketName);
+ });
+
+ it('dispatches bucket-selected event when a bucket is selected', function () {
+ $bucketName = 'production-bucket';
+
+ Livewire::test(Buckets::class)
+ ->call('selectBucket', $bucketName)
+ ->assertDispatched('bucket-selected', bucketName: $bucketName);
+ });
+
+ it('returns null for active bucket when none is selected', function () {
+ Livewire::test(Buckets::class)
+ ->assertSet('activeBucket', null);
+ });
+
+ it('returns active bucket from settings', function () {
+ $bucketName = 'stored-bucket';
+ Settings::set('active-bucket', $bucketName);
+
+ Livewire::test(Buckets::class)
+ ->assertSet('activeBucket', $bucketName);
+ });
+
+ it('refreshes buckets when region is switched', function () {
+ $credential = Credential::factory()->create();
+ Settings::set('active-account', $credential->id);
+
+ $component = Livewire::test(Buckets::class);
+
+ // Trigger the event
+ $component->dispatch('region-switched');
+
+ // Component should still render successfully after refresh
+ $component->assertStatus(200);
+ });
+
+ it('returns empty collection when no credential is set', function () {
+ Settings::forget('active-account');
+
+ $component = Livewire::test(Buckets::class);
+
+ expect($component->get('buckets'))->toBeEmpty();
+ });
+
+ it('returns empty collection when credential does not exist', function () {
+ Settings::set('active-account', 'non-existent-id');
+
+ $component = Livewire::test(Buckets::class);
+
+ expect($component->get('buckets'))->toBeEmpty();
+ });
+});