feat: catalog add loading spinner

This commit is contained in:
Benjamin Nussbaum 2025-11-14 18:39:12 +01:00
parent 468e8a130d
commit 22a24383b2
3 changed files with 44 additions and 24 deletions

View file

@ -1,6 +1,7 @@
<?php
use App\Services\PluginImportService;
use Livewire\Attributes\Lazy;
use Livewire\Volt\Component;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
@ -8,7 +9,9 @@ use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Symfony\Component\Yaml\Yaml;
new class extends Component {
new
#[Lazy]
class extends Component {
public array $catalogPlugins = [];
public string $installingPlugin = '';
@ -17,6 +20,20 @@ new class extends Component {
$this->loadCatalogPlugins();
}
public function placeholder()
{
return <<<'HTML'
<div class="space-y-4">
<div class="flex items-center justify-center py-12">
<div class="flex items-center space-x-2">
<flux:icon.loading />
<flux:text>Loading recipes...</flux:text>
</div>
</div>
</div>
HTML;
}
private function loadCatalogPlugins(): void
{
$catalogUrl = config('app.catalog_url');

View file

@ -1,5 +1,6 @@
<?php
use Livewire\Attributes\Lazy;
use Livewire\Volt\Component;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
@ -7,17 +8,32 @@ use Illuminate\Support\Facades\Cache;
use App\Services\PluginImportService;
use Illuminate\Support\Facades\Auth;
new class extends Component {
new
#[Lazy]
class extends Component {
public array $recipes = [];
public string $search = '';
public bool $isSearching = false;
public string $installingPlugin = '';
public function mount(): void
{
$this->loadNewest();
}
public function placeholder()
{
return <<<'HTML'
<div class="space-y-4">
<div class="flex items-center justify-center py-12">
<div class="flex items-center space-x-2">
<flux:icon.loading />
<flux:text>Loading recipes...</flux:text>
</div>
</div>
</div>
HTML;
}
private function loadNewest(): void
{
try {
@ -87,8 +103,6 @@ new class extends Component {
{
abort_unless(auth()->user() !== null, 403);
$this->installingPlugin = $recipeId;
try {
$zipUrl = "https://usetrmnl.com/api/plugin_settings/{$recipeId}/archive";
@ -108,8 +122,6 @@ new class extends Component {
} catch (\Exception $e) {
Log::error('Plugin installation failed: ' . $e->getMessage());
$this->addError('installation', 'Error installing plugin: ' . $e->getMessage());
} finally {
$this->installingPlugin = '';
}
}
@ -199,21 +211,12 @@ new class extends Component {
<div class="mt-4 flex items-center space-x-3">
@if($recipe['id'])
@if($installingPlugin === $recipe['id'])
<flux:button
wire:click="installPlugin('{{ $recipe['id'] }}')"
variant="primary"
disabled>
<flux:icon name="arrow-path" class="w-4 h-4 animate-spin" />
</flux:button>
@else
<flux:button
wire:click="installPlugin('{{ $recipe['id'] }}')"
variant="primary">
Install
</flux:button>
@endif
@endif
@if($recipe['detail_url'])
<flux:button

View file

@ -286,7 +286,7 @@ new class extends Component {
</flux:heading>
<flux:subheading>Browse and install Recipes from the community. Add yours <a href="https://github.com/bnussbau/trmnl-recipe-catalog" class="underline" target="_blank">here</a>.</flux:subheading>
</div>
<livewire:catalog.index lazy />
<livewire:catalog.index />
</div>
</flux:modal>
@ -300,14 +300,14 @@ new class extends Component {
<flux:heading size="sm">Limitations</flux:heading>
<ul class="list-disc pl-5 mt-2">
<li><flux:text>Only full view will be imported; shared markup will be prepended</flux:text></li>
<li><flux:text>Requires <span class="font-mono">trmnl-liquid-cli</span>. (Included in Docker container)</flux:text></li>
<li><flux:text>Requires <span class="font-mono">trmnl-liquid-cli</span> executable.</flux:text></li>
<li><flux:text>API responses in formats other than <span class="font-mono">JSON</span> are not yet fully supported.</flux:text></li>
<li><flux:text>There are limitations in payload size (Data Payload, Template).</flux:text></li>
</ul>
<flux:text class="mt-1">Please report issues, aside from the known limitations, on <a href="https://github.com/usetrmnl/byos_laravel/issues/new" target="_blank" class="underline">GitHub</a>. Include the recipe URL.</flux:text></li>
</flux:callout>
</div>
<livewire:catalog.trmnl lazy />
<livewire:catalog.trmnl />
</div>
</flux:modal>