fix: services file/dir read from server
ui: fix storages layout
This commit is contained in:
@@ -29,7 +29,10 @@ class Index extends Component
|
|||||||
$this->parameters = get_route_parameters();
|
$this->parameters = get_route_parameters();
|
||||||
$this->query = request()->query();
|
$this->query = request()->query();
|
||||||
$this->service = Service::whereUuid($this->parameters['service_uuid'])->firstOrFail();
|
$this->service = Service::whereUuid($this->parameters['service_uuid'])->firstOrFail();
|
||||||
$this->refreshStack();
|
$this->applications = $this->service->applications->sort();
|
||||||
|
$this->databases = $this->service->databases->sort();
|
||||||
|
ray($this->applications);
|
||||||
|
ray($this->databases);
|
||||||
}
|
}
|
||||||
public function saveCompose($raw)
|
public function saveCompose($raw)
|
||||||
{
|
{
|
||||||
|
|||||||
35
app/Http/Livewire/Project/Service/Storage.php
Normal file
35
app/Http/Livewire/Project/Service/Storage.php
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Livewire\Project\Service;
|
||||||
|
|
||||||
|
use App\Models\LocalPersistentVolume;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class Storage extends Component
|
||||||
|
{
|
||||||
|
protected $listeners = ['addNewVolume'];
|
||||||
|
public $resource;
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.project.service.storage');
|
||||||
|
}
|
||||||
|
public function addNewVolume($data)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
LocalPersistentVolume::create([
|
||||||
|
'name' => $data['name'],
|
||||||
|
'mount_path' => $data['mount_path'],
|
||||||
|
'host_path' => $data['host_path'],
|
||||||
|
'resource_id' => $this->resource->id,
|
||||||
|
'resource_type' => $this->resource->getMorphClass(),
|
||||||
|
]);
|
||||||
|
$this->resource->refresh();
|
||||||
|
$this->emit('success', 'Storage added successfully');
|
||||||
|
$this->emit('clearAddStorage');
|
||||||
|
$this->emit('refreshStorages');
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ class Add extends Component
|
|||||||
{
|
{
|
||||||
$this->validate();
|
$this->validate();
|
||||||
$name = $this->uuid . '-' . $this->name;
|
$name = $this->uuid . '-' . $this->name;
|
||||||
$this->emitUp('submit', [
|
$this->emit('addNewVolume', [
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'mount_path' => $this->mount_path,
|
'mount_path' => $this->mount_path,
|
||||||
'host_path' => $this->host_path,
|
'host_path' => $this->host_path,
|
||||||
|
|||||||
@@ -7,30 +7,11 @@ use Livewire\Component;
|
|||||||
|
|
||||||
class All extends Component
|
class All extends Component
|
||||||
{
|
{
|
||||||
public bool $isHeaderVisible = true;
|
|
||||||
public $resource;
|
public $resource;
|
||||||
protected $listeners = ['refreshStorages', 'submit'];
|
protected $listeners = ['refreshStorages'];
|
||||||
|
|
||||||
public function refreshStorages()
|
public function refreshStorages()
|
||||||
{
|
{
|
||||||
$this->resource->refresh();
|
$this->resource->refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function submit($data)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
LocalPersistentVolume::create([
|
|
||||||
'name' => $data['name'],
|
|
||||||
'mount_path' => $data['mount_path'],
|
|
||||||
'host_path' => $data['host_path'],
|
|
||||||
'resource_id' => $this->resource->id,
|
|
||||||
'resource_type' => $this->resource->getMorphClass(),
|
|
||||||
]);
|
|
||||||
$this->resource->refresh();
|
|
||||||
$this->emit('success', 'Storage added successfully');
|
|
||||||
$this->emit('clearAddStorage');
|
|
||||||
} catch (\Throwable $e) {
|
|
||||||
return handleError($e, $this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,10 @@ class Application extends BaseModel
|
|||||||
{
|
{
|
||||||
return $this->morphMany(LocalPersistentVolume::class, 'resource');
|
return $this->morphMany(LocalPersistentVolume::class, 'resource');
|
||||||
}
|
}
|
||||||
|
public function fileStorages()
|
||||||
|
{
|
||||||
|
return $this->morphMany(LocalFileVolume::class, 'resource');
|
||||||
|
}
|
||||||
|
|
||||||
public function type()
|
public function type()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,23 +31,18 @@ class LocalFileVolume extends BaseModel
|
|||||||
}
|
}
|
||||||
$isFile = instant_remote_process(["test -f $path && echo OK || echo NOK"], $server);
|
$isFile = instant_remote_process(["test -f $path && echo OK || echo NOK"], $server);
|
||||||
$isDir = instant_remote_process(["test -d $path && echo OK || echo NOK"], $server);
|
$isDir = instant_remote_process(["test -d $path && echo OK || echo NOK"], $server);
|
||||||
ray($isFile);
|
|
||||||
if ($isFile == 'OK' && $fileVolume->is_directory) {
|
if ($isFile == 'OK' && $fileVolume->is_directory) {
|
||||||
throw new \Exception("File $path is a file on the server, but you are trying to mark it as a directory. Please delete the file on the server or mark it as directory.");
|
throw new \Exception("File $path is a file on the server, but you are trying to mark it as a directory. Please delete the file on the server or mark it as directory.");
|
||||||
} else if ($isDir == 'OK' && !$fileVolume->is_directory) {
|
} else if ($isDir == 'OK' && !$fileVolume->is_directory) {
|
||||||
throw new \Exception("File $path is a directory on the server, but you are trying to mark it as a file. Please delete the directory on the server or mark it as directory.");
|
throw new \Exception("File $path is a directory on the server, but you are trying to mark it as a file. Please delete the directory on the server or mark it as directory.");
|
||||||
}
|
}
|
||||||
if (($isFile == 'NOK' && !$fileVolume->is_directory) || $isFile == 'OK') {
|
if (!$fileVolume->is_directory && $isDir == 'NOK') {
|
||||||
$rootDir = Str::of($path)->dirname();
|
|
||||||
$commands->push("mkdir -p $rootDir > /dev/null 2>&1 || true");
|
|
||||||
$commands->push("touch $path > /dev/null 2>&1 || true");
|
|
||||||
if ($content) {
|
|
||||||
$content = base64_encode($content);
|
$content = base64_encode($content);
|
||||||
$commands->push("echo '$content' | base64 -d > $path");
|
$commands->push("echo '$content' | base64 -d > $path");
|
||||||
}
|
|
||||||
} else if ($isDir == 'NOK' && $fileVolume->is_directory) {
|
} else if ($isDir == 'NOK' && $fileVolume->is_directory) {
|
||||||
$commands->push("mkdir -p $path > /dev/null 2>&1 || true");
|
$commands->push("mkdir -p $path > /dev/null 2>&1 || true");
|
||||||
}
|
}
|
||||||
|
ray($commands->toArray());
|
||||||
return instant_remote_process($commands, $server);
|
return instant_remote_process($commands, $server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,11 @@ class StandalonePostgresql extends BaseModel
|
|||||||
return $this->belongsTo(Environment::class);
|
return $this->belongsTo(Environment::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function fileStorages()
|
||||||
|
{
|
||||||
|
return $this->morphMany(LocalFileVolume::class, 'resource');
|
||||||
|
}
|
||||||
|
|
||||||
public function destination()
|
public function destination()
|
||||||
{
|
{
|
||||||
return $this->morphTo();
|
return $this->morphTo();
|
||||||
|
|||||||
@@ -85,28 +85,39 @@ function getFilesystemVolumesFromServer(ServiceApplication|ServiceDatabase $oneS
|
|||||||
} else {
|
} else {
|
||||||
$fileLocation = $path;
|
$fileLocation = $path;
|
||||||
}
|
}
|
||||||
|
ray($path,$fileLocation);
|
||||||
|
// Exists and is a file
|
||||||
$isFile = instant_remote_process(["test -f $fileLocation && echo OK || echo NOK"], $server);
|
$isFile = instant_remote_process(["test -f $fileLocation && echo OK || echo NOK"], $server);
|
||||||
|
// Exists and is a directory
|
||||||
$isDir = instant_remote_process(["test -d $fileLocation && echo OK || echo NOK"], $server);
|
$isDir = instant_remote_process(["test -d $fileLocation && echo OK || echo NOK"], $server);
|
||||||
if ($isFile === 'NOK' &&!$fileVolume->is_directory && $isInit) {
|
|
||||||
$fileVolume->saveStorageOnServer($oneService);
|
if ($isFile == 'OK') {
|
||||||
continue;
|
// If its a file & exists
|
||||||
}
|
|
||||||
if ($isFile == 'OK' && !$fileVolume->is_directory) {
|
|
||||||
$filesystemContent = instant_remote_process(["cat $fileLocation"], $server);
|
$filesystemContent = instant_remote_process(["cat $fileLocation"], $server);
|
||||||
if (base64_encode($filesystemContent) != base64_encode($content)) {
|
|
||||||
$fileVolume->content = $filesystemContent;
|
$fileVolume->content = $filesystemContent;
|
||||||
|
$fileVolume->is_directory = false;
|
||||||
$fileVolume->save();
|
$fileVolume->save();
|
||||||
}
|
} else if ($isDir == 'OK') {
|
||||||
} else {
|
// If its a directory & exists
|
||||||
if ($isDir == 'OK') {
|
|
||||||
$fileVolume->content = null;
|
$fileVolume->content = null;
|
||||||
$fileVolume->is_directory = true;
|
$fileVolume->is_directory = true;
|
||||||
$fileVolume->save();
|
$fileVolume->save();
|
||||||
} else {
|
} else if ($isFile == 'NOK' && $isDir == 'NOK' && !$fileVolume->is_directory && $isInit && $content) {
|
||||||
$fileVolume->content = null;
|
// Does not exists (no dir or file), not flagged as directory, is init, has content
|
||||||
|
$fileVolume->content = $content;
|
||||||
$fileVolume->is_directory = false;
|
$fileVolume->is_directory = false;
|
||||||
$fileVolume->save();
|
$fileVolume->save();
|
||||||
}
|
$content = base64_encode($content);
|
||||||
|
$dir = Str::of($fileLocation)->dirname();
|
||||||
|
instant_remote_process([
|
||||||
|
"mkdir -p $dir",
|
||||||
|
"echo '$content' | base64 -d > $fileLocation"
|
||||||
|
], $server);
|
||||||
|
} else if ($isFile == 'NOK' && $isDir == 'NOK' && $fileVolume->is_directory && $isInit) {
|
||||||
|
$fileVolume->content = null;
|
||||||
|
$fileVolume->is_directory = true;
|
||||||
|
$fileVolume->save();
|
||||||
|
instant_remote_process(["mkdir -p $fileLocation"], $server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div x-data="{ raw: true, activeTab: window.location.hash ? window.location.hash.substring(1) : 'service-stack' }" wire:poll.10000ms="checkStatus">
|
<div x-data="{ raw: true, activeTab: window.location.hash ? window.location.hash.substring(1) : 'service-stack' }" wire:poll.2000ms="checkStatus">
|
||||||
<livewire:project.service.navbar :service="$service" :parameters="$parameters" :query="$query" />
|
<livewire:project.service.navbar :service="$service" :parameters="$parameters" :query="$query" />
|
||||||
<livewire:project.service.compose-modal :raw="$service->docker_compose_raw" :actual="$service->docker_compose" />
|
<livewire:project.service.compose-modal :raw="$service->docker_compose_raw" :actual="$service->docker_compose" />
|
||||||
<div class="flex h-full pt-6">
|
<div class="flex h-full pt-6">
|
||||||
@@ -102,42 +102,18 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'storages'">
|
<div x-cloak x-show="activeTab === 'storages'">
|
||||||
@foreach ($applications as $application)
|
<div class="flex items-center gap-2">
|
||||||
@if ($loop->first)
|
<h2>Storages</h2>
|
||||||
<livewire:project.shared.storages.all :resource="$application" />
|
|
||||||
@else
|
|
||||||
<livewire:project.shared.storages.all :resource="$application" :isHeaderVisible="false" />
|
|
||||||
@endif
|
|
||||||
@if ($application->fileStorages()->get()->count() > 0)
|
|
||||||
<h5 class="py-4">Mounted Files/Dirs (binds)</h5>
|
|
||||||
<div class="flex flex-col gap-4">
|
|
||||||
@foreach ($application->fileStorages()->get()->sort() as $fileStorage)
|
|
||||||
<livewire:project.service.file-storage :fileStorage="$fileStorage"
|
|
||||||
wire:key="{{ $loop->index }}" />
|
|
||||||
@endforeach
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
<div class="pb-4">Persistent storage to preserve data between deployments.</div>
|
||||||
|
<span class="text-warning">Please modify storage layout in your <a class="underline"
|
||||||
|
href="{{ Str::of(url()->current())->beforeLast('/') }}">Docker Compose</a> file.</span>
|
||||||
|
@foreach ($applications as $application)
|
||||||
|
<livewire:project.service.storage wire:key="application-{{ $application->id }}"
|
||||||
|
:resource="$application" />
|
||||||
@endforeach
|
@endforeach
|
||||||
@foreach ($databases as $database)
|
@foreach ($databases as $database)
|
||||||
@if ($loop->first)
|
<livewire:project.service.storage wire:key="database-{{ $database->id }}" :resource="$database" />
|
||||||
<h3 class="pt-4">{{ Str::headline($database->name) }}</h3>
|
|
||||||
@if ($applications->count() > 0)
|
|
||||||
<livewire:project.shared.storages.all :resource="$database" :isHeaderVisible="false" />
|
|
||||||
@else
|
|
||||||
<livewire:project.shared.storages.all :resource="$database" />
|
|
||||||
@endif
|
|
||||||
@if ($database->fileStorages()->get()->count() > 0)
|
|
||||||
<h5 class="py-4">Mounted Files/Dirs (binds)</h5>
|
|
||||||
<div class="flex flex-col gap-4">
|
|
||||||
@foreach ($database->fileStorages()->get()->sort() as $fileStorage)
|
|
||||||
<livewire:project.service.file-storage :fileStorage="$fileStorage"
|
|
||||||
wire:key="{{ $loop->index }}" />
|
|
||||||
@endforeach
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
@else
|
|
||||||
<livewire:project.shared.storages.all :resource="$database" :isHeaderVisible="false" />
|
|
||||||
@endif
|
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -24,15 +24,14 @@
|
|||||||
<livewire:project.service.application :application="$serviceApplication" />
|
<livewire:project.service.application :application="$serviceApplication" />
|
||||||
</div>
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'storages'">
|
<div x-cloak x-show="activeTab === 'storages'">
|
||||||
<livewire:project.shared.storages.all :resource="$serviceApplication" />
|
<div class="flex items-center gap-2">
|
||||||
@if ($serviceApplication->fileStorages()->get()->count() > 0)
|
<h2>Storages</h2>
|
||||||
<h5 class="py-4">Mounted Files/Dirs (binds)</h5>
|
|
||||||
<div class="flex flex-col gap-4">
|
|
||||||
@foreach ($serviceApplication->fileStorages()->get()->sort() as $fileStorage)
|
|
||||||
<livewire:project.service.file-storage :fileStorage="$fileStorage" wire:key="{{ $loop->index }}" />
|
|
||||||
@endforeach
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
<div class="pb-4">Persistent storage to preserve data between deployments.</div>
|
||||||
|
<span class="text-warning">Please modify storage layout in your <a class="underline"
|
||||||
|
href="{{ Str::of(url()->current())->beforeLast('/') }}">Docker Compose</a> file.</span>
|
||||||
|
<livewire:project.service.storage wire:key="application-{{ $serviceApplication->id }}"
|
||||||
|
:resource="$serviceApplication" />
|
||||||
</div>
|
</div>
|
||||||
@endisset
|
@endisset
|
||||||
@isset($serviceDatabase)
|
@isset($serviceDatabase)
|
||||||
@@ -40,15 +39,14 @@
|
|||||||
<livewire:project.service.database :database="$serviceDatabase" />
|
<livewire:project.service.database :database="$serviceDatabase" />
|
||||||
</div>
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'storages'">
|
<div x-cloak x-show="activeTab === 'storages'">
|
||||||
<livewire:project.shared.storages.all :resource="$serviceDatabase" />
|
<div class="flex items-center gap-2">
|
||||||
@if ($serviceDatabase->fileStorages()->get()->count() > 0)
|
<h2>Storages</h2>
|
||||||
<h5 class="py-4">Mounted Files/Dirs (binds)</h5>
|
|
||||||
<div class="flex flex-col gap-4">
|
|
||||||
@foreach ($serviceDatabase->fileStorages()->get()->sort() as $fileStorage)
|
|
||||||
<livewire:project.service.file-storage :fileStorage="$fileStorage" wire:key="{{ $loop->index }}" />
|
|
||||||
@endforeach
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
<div class="pb-4">Persistent storage to preserve data between deployments.</div>
|
||||||
|
<span class="text-warning">Please modify storage layout in your <a class="underline"
|
||||||
|
href="{{ Str::of(url()->current())->beforeLast('/') }}">Docker Compose</a> file.</span>
|
||||||
|
<livewire:project.service.storage wire:key="application-{{ $serviceDatabase->id }}"
|
||||||
|
:resource="$serviceDatabase" />
|
||||||
</div>
|
</div>
|
||||||
@endisset
|
@endisset
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
49
resources/views/livewire/project/service/storage.blade.php
Normal file
49
resources/views/livewire/project/service/storage.blade.php
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<div>
|
||||||
|
@if (
|
||||||
|
$resource->getMorphClass() == 'App\Models\Application' ||
|
||||||
|
$resource->getMorphClass() == 'App\Models\StandalonePostgresql')
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<h2>Storages</h2>
|
||||||
|
<x-helper
|
||||||
|
helper="For Preview Deployments, storage has a <span class='text-helper'>-pr-#PRNumber</span> in their
|
||||||
|
volume
|
||||||
|
name, example: <span class='text-helper'>-pr-1</span>" />
|
||||||
|
<x-forms.button class="btn" onclick="newStorage.showModal()">+ Add</x-forms.button>
|
||||||
|
<livewire:project.shared.storages.add :uuid="$resource->uuid" />
|
||||||
|
</div>
|
||||||
|
<div class="pb-4">Persistent storage to preserve data between deployments.</div>
|
||||||
|
@if (
|
||||||
|
$resource->persistentStorages()->get()->count() === 0 &&
|
||||||
|
$resource->fileStorages()->get()->count() == 0)
|
||||||
|
<div>No storage found.</div>
|
||||||
|
@else
|
||||||
|
@if ($resource->persistentStorages()->get()->count() > 0)
|
||||||
|
<livewire:project.shared.storages.all :resource="$resource" />
|
||||||
|
@endif
|
||||||
|
@if ($resource->fileStorages()->get()->count() > 0)
|
||||||
|
<div class="flex flex-col gap-4 pt-4">
|
||||||
|
@foreach ($resource->fileStorages()->get()->sort() as $fileStorage)
|
||||||
|
<livewire:project.service.file-storage :fileStorage="$fileStorage"
|
||||||
|
wire:key="resource-{{ $resource->uuid }}" />
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@endif
|
||||||
|
@else
|
||||||
|
@if (
|
||||||
|
$resource->persistentStorages()->get()->count() > 0 ||
|
||||||
|
$resource->fileStorages()->get()->count() > 0)
|
||||||
|
<h3 class="pt-4">{{ Str::headline($resource->name) }} </h3>
|
||||||
|
@endif
|
||||||
|
@if ($resource->persistentStorages()->get()->count() > 0)
|
||||||
|
<livewire:project.shared.storages.all :resource="$resource" />
|
||||||
|
@endif
|
||||||
|
@if ($resource->fileStorages()->get()->count() > 0)
|
||||||
|
<div class="flex flex-col gap-4 pt-4">
|
||||||
|
@foreach ($resource->fileStorages()->get()->sort() as $fileStorage)
|
||||||
|
<livewire:project.service.file-storage :fileStorage="$fileStorage" wire:key="resource-{{ $resource->uuid }}" />
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
@@ -1,25 +1,4 @@
|
|||||||
<div>
|
<div>
|
||||||
@if ($isHeaderVisible)
|
|
||||||
<div>
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<h2>Storages</h2>
|
|
||||||
@if ($resource->type() !== 'service')
|
|
||||||
<x-helper
|
|
||||||
helper="For Preview Deployments, storage has a <span class='text-helper'>-pr-#PRNumber</span> in their
|
|
||||||
volume
|
|
||||||
name, example: <span class='text-helper'>-pr-1</span>" />
|
|
||||||
<x-forms.button class="btn" onclick="newStorage.showModal()">+ Add</x-forms.button>
|
|
||||||
<livewire:project.shared.storages.add :uuid="$resource->uuid" />
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
<div class="pb-4">Persistent storage to preserve data between deployments.</div>
|
|
||||||
@if ($resource->type() === 'service')
|
|
||||||
<span class="text-warning">Please modify storage layout in your <a class="underline"
|
|
||||||
href="{{ Str::of(url()->current())->beforeLast('/') }}">Docker Compose</a> file.</span>
|
|
||||||
<h2 class="pt-4">{{ Str::headline($resource->name) }} </h2>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
@foreach ($resource->persistentStorages as $storage)
|
@foreach ($resource->persistentStorages as $storage)
|
||||||
@if ($resource->type() === 'service')
|
@if ($resource->type() === 'service')
|
||||||
|
|||||||
@@ -14,8 +14,7 @@
|
|||||||
@click.prevent="activeTab = 'source'; window.location.hash = 'source'" href="#">Source</a>
|
@click.prevent="activeTab = 'source'; window.location.hash = 'source'" href="#">Source</a>
|
||||||
@endif
|
@endif
|
||||||
<a :class="activeTab === 'server' && 'text-white'"
|
<a :class="activeTab === 'server' && 'text-white'"
|
||||||
@click.prevent="activeTab = 'server'; window.location.hash = 'server'"
|
@click.prevent="activeTab = 'server'; window.location.hash = 'server'" href="#">Server
|
||||||
href="#">Server
|
|
||||||
</a>
|
</a>
|
||||||
<a :class="activeTab === 'storages' && 'text-white'"
|
<a :class="activeTab === 'storages' && 'text-white'"
|
||||||
@click.prevent="activeTab = 'storages'; window.location.hash = 'storages'" href="#">Storages
|
@click.prevent="activeTab = 'storages'; window.location.hash = 'storages'" href="#">Storages
|
||||||
@@ -56,7 +55,7 @@
|
|||||||
<livewire:project.shared.destination :destination="$application->destination" />
|
<livewire:project.shared.destination :destination="$application->destination" />
|
||||||
</div>
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'storages'">
|
<div x-cloak x-show="activeTab === 'storages'">
|
||||||
<livewire:project.shared.storages.all :resource="$application" />
|
<livewire:project.service.storage :resource="$application" />
|
||||||
</div>
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'previews'">
|
<div x-cloak x-show="activeTab === 'previews'">
|
||||||
<livewire:project.application.previews :application="$application" />
|
<livewire:project.application.previews :application="$application" />
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
<livewire:project.shared.destination :destination="$database->destination" />
|
<livewire:project.shared.destination :destination="$database->destination" />
|
||||||
</div>
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'storages'">
|
<div x-cloak x-show="activeTab === 'storages'">
|
||||||
<livewire:project.shared.storages.all :resource="$database" />
|
<livewire:project.service.storage :resource="$database" />
|
||||||
</div>
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'resource-limits'">
|
<div x-cloak x-show="activeTab === 'resource-limits'">
|
||||||
<livewire:project.shared.resource-limits :resource="$database" />
|
<livewire:project.shared.resource-limits :resource="$database" />
|
||||||
|
|||||||
Reference in New Issue
Block a user