feat(ui): add resource details view

This commit is contained in:
ShadowArcanist
2026-04-23 14:53:31 +05:30
parent 37518813a6
commit 3f88e85aac
16 changed files with 191 additions and 6 deletions
@@ -35,7 +35,7 @@ class Configuration extends Component
$project = currentTeam()
->projects()
->select('id', 'uuid', 'team_id')
->select('id', 'uuid', 'name', 'team_id')
->where('uuid', request()->route('project_uuid'))
->firstOrFail();
$environment = $project->environments()
@@ -34,7 +34,7 @@ class Configuration extends Component
$project = currentTeam()
->projects()
->select('id', 'uuid', 'team_id')
->select('id', 'uuid', 'name', 'team_id')
->where('uuid', request()->route('project_uuid'))
->firstOrFail();
$environment = $project->environments()
@@ -51,7 +51,7 @@ class Configuration extends Component
$this->query = request()->query();
$project = currentTeam()
->projects()
->select('id', 'uuid', 'team_id')
->select('id', 'uuid', 'name', 'team_id')
->where('uuid', request()->route('project_uuid'))
->firstOrFail();
$environment = $project->environments()
@@ -0,0 +1,91 @@
<?php
namespace App\Livewire\Project\Shared;
use App\Models\Service;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Component;
class ResourceDetails extends Component
{
use AuthorizesRequests;
public $resource;
public ?string $project_uuid = null;
public ?string $project_name = null;
public ?string $environment_uuid = null;
public ?string $environment_name = null;
public ?string $server_uuid = null;
public ?string $server_name = null;
public array $stack_applications = [];
public array $stack_databases = [];
public function mount()
{
$this->authorize('view', $this->resource);
$environment = $this->resource->environment ?? null;
if ($environment) {
$this->environment_uuid = $environment->uuid;
$this->environment_name = $environment->name;
$project = $environment->project ?? null;
if ($project) {
$this->project_uuid = $project->uuid;
$this->project_name = $project->name;
}
}
$server = $this->resolveServer();
if ($server) {
$this->server_uuid = $server->uuid;
$this->server_name = $server->name;
}
if ($this->resource instanceof Service) {
$this->stack_applications = $this->resource->applications
->map(fn ($app) => [
'name' => $app->human_name ?: $app->name,
'uuid' => $app->uuid,
])
->values()
->all();
$this->stack_databases = $this->resource->databases
->map(fn ($db) => [
'name' => $db->human_name ?: $db->name,
'uuid' => $db->uuid,
])
->values()
->all();
}
}
private function resolveServer()
{
try {
if (isset($this->resource->destination) && $this->resource->destination && isset($this->resource->destination->server)) {
return $this->resource->destination->server;
}
if (method_exists($this->resource, 'server') && $this->resource->server) {
return $this->resource->server;
}
} catch (\Throwable $e) {
return null;
}
return null;
}
public function render()
{
return view('livewire.project.shared.resource-details');
}
}
@@ -1,7 +1,13 @@
@props(['text'])
@props(['text', 'label' => null])
<div class="relative" x-data="{ copied: false, isSecure: window.isSecureContext }">
<input type="text" value="{{ $text }}" readonly class="input">
<div class="w-full" x-data="{ copied: false, isSecure: window.isSecureContext }">
@if ($label)
<label class="flex gap-1 items-center mb-1 text-sm font-medium">{{ $label }}</label>
@endif
<div class="relative">
<input type="text" value="{{ $text }}" class="input pr-10"
@keydown.prevent @paste.prevent @cut.prevent @drop.prevent
@focus="$event.target.select()">
<button
x-show="isSecure"
@click.prevent="copied = true; navigator.clipboard.writeText({{ Js::from($text) }}); setTimeout(() => copied = false, 1000)"
@@ -15,4 +21,5 @@
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
</svg>
</button>
</div>
</div>
@@ -12,6 +12,9 @@
<div>{{ $application->compose_parsing_version }}</div>
@endif
<x-forms.button canGate="update" :canResource="$application" type="submit">Save</x-forms.button>
<x-modal-input title="Resource Details" buttonTitle="Details">
<livewire:project.shared.resource-details :resource="$application" />
</x-modal-input>
@if ($buildPack === 'dockercompose')
<x-forms.button canGate="update" :canResource="$application" wire:target='initLoadingCompose'
x-on:click="$wire.dispatch('loadCompose', false)">
@@ -5,6 +5,9 @@
<x-forms.button type="submit" canGate="update" :canResource="$database">
Save
</x-forms.button>
<x-modal-input title="Resource Details" buttonTitle="Details">
<livewire:project.shared.resource-details :resource="$database" />
</x-modal-input>
</div>
<div class="flex gap-2">
<x-forms.input label="Name" id="name" canGate="update" :canResource="$database" />
@@ -5,6 +5,9 @@
<x-forms.button type="submit" canGate="update" :canResource="$database">
Save
</x-forms.button>
<x-modal-input title="Resource Details" buttonTitle="Details">
<livewire:project.shared.resource-details :resource="$database" />
</x-modal-input>
</div>
<div class="flex gap-2">
<x-forms.input label="Name" id="name" canGate="update" :canResource="$database" />
@@ -5,6 +5,9 @@
<x-forms.button type="submit" canGate="update" :canResource="$database">
Save
</x-forms.button>
<x-modal-input title="Resource Details" buttonTitle="Details">
<livewire:project.shared.resource-details :resource="$database" />
</x-modal-input>
</div>
<div class="flex gap-2">
<x-forms.input label="Name" id="name" canGate="update" :canResource="$database" />
@@ -5,6 +5,9 @@
<x-forms.button type="submit" canGate="update" :canResource="$database">
Save
</x-forms.button>
<x-modal-input title="Resource Details" buttonTitle="Details">
<livewire:project.shared.resource-details :resource="$database" />
</x-modal-input>
</div>
<div class="flex gap-2">
<x-forms.input label="Name" id="name" canGate="update" :canResource="$database" />
@@ -5,6 +5,9 @@
<x-forms.button type="submit" canGate="update" :canResource="$database">
Save
</x-forms.button>
<x-modal-input title="Resource Details" buttonTitle="Details">
<livewire:project.shared.resource-details :resource="$database" />
</x-modal-input>
</div>
<div class="flex gap-2">
<x-forms.input label="Name" id="name" canGate="update" :canResource="$database" />
@@ -5,6 +5,9 @@
<x-forms.button type="submit">
Save
</x-forms.button>
<x-modal-input title="Resource Details" buttonTitle="Details">
<livewire:project.shared.resource-details :resource="$database" />
</x-modal-input>
</div>
<div class="flex gap-2">
<x-forms.input label="Name" id="name" canGate="update" :canResource="$database" />
@@ -19,6 +19,9 @@
<x-forms.button type="submit" canGate="update" :canResource="$database">
Save
</x-forms.button>
<x-modal-input title="Resource Details" buttonTitle="Details">
<livewire:project.shared.resource-details :resource="$database" />
</x-modal-input>
</div>
<div class="flex flex-wrap gap-2 sm:flex-nowrap">
<x-forms.input label="Name" id="name" canGate="update" :canResource="$database" />
@@ -5,6 +5,9 @@
<x-forms.button type="submit" canGate="update" :canResource="$database">
Save
</x-forms.button>
<x-modal-input title="Resource Details" buttonTitle="Details">
<livewire:project.shared.resource-details :resource="$database" />
</x-modal-input>
</div>
<div class="flex gap-2">
<x-forms.input label="Name" id="name" canGate="update" :canResource="$database" />
@@ -12,6 +12,9 @@
<livewire:project.service.edit-compose serviceId="{{ $service->id }}" />
</x-modal-input>
@endcan
<x-modal-input title="Resource Details" buttonTitle="Details">
<livewire:project.shared.resource-details :resource="$service" />
</x-modal-input>
</div>
<div>Configuration</div>
</div>
@@ -0,0 +1,57 @@
<div class="w-full max-h-[70vh] overflow-y-auto pr-1 -mt-4">
<div class="pb-4 text-sm dark:text-neutral-400">Identifiers for this resource. Read-only</div>
<div class="flex flex-col gap-6">
<div>
<h3>Resource</h3>
<div class="pt-2 grid grid-cols-1 gap-3 md:grid-cols-2">
<x-forms.copy-button label="Name" :text="$resource->name ?? ''" />
<x-forms.copy-button label="UUID" :text="$resource->uuid ?? ''" />
</div>
</div>
@if ($environment_uuid)
<div>
<h3>Environment</h3>
<div class="pt-2 grid grid-cols-1 gap-3 md:grid-cols-2">
<x-forms.copy-button label="Name" :text="$environment_name ?? ''" />
<x-forms.copy-button label="UUID" :text="$environment_uuid" />
</div>
</div>
@endif
@if ($project_uuid)
<div>
<h3>Project</h3>
<div class="pt-2 grid grid-cols-1 gap-3 md:grid-cols-2">
<x-forms.copy-button label="Name" :text="$project_name ?? ''" />
<x-forms.copy-button label="UUID" :text="$project_uuid" />
</div>
</div>
@endif
@if ($server_uuid)
<div>
<h3>Server</h3>
<div class="pt-2 grid grid-cols-1 gap-3 md:grid-cols-2">
<x-forms.copy-button label="Name" :text="$server_name ?? ''" />
<x-forms.copy-button label="UUID" :text="$server_uuid" />
</div>
</div>
@endif
@if (! empty($stack_applications) || ! empty($stack_databases))
<div>
<h3>Stack Sub-Resources</h3>
<div class="pt-2 grid grid-cols-1 gap-3 md:grid-cols-2">
@foreach ($stack_applications as $item)
<x-forms.copy-button :label="'Application — ' . $item['name']" :text="$item['uuid']" />
@endforeach
@foreach ($stack_databases as $item)
<x-forms.copy-button :label="'Database — ' . $item['name']" :text="$item['uuid']" />
@endforeach
</div>
</div>
@endif
</div>
</div>