feat: move resources between projects / environments

This commit is contained in:
Andras Bacsai
2024-01-22 15:12:38 +01:00
parent cbec39099a
commit 2edf71a0dd
7 changed files with 228 additions and 128 deletions

View File

@@ -59,7 +59,9 @@
href="#">Resource Limits
</a>
@endif
<a :class="activeTab === 'move' && 'text-white'"
@click.prevent="activeTab = 'move'; window.location.hash = 'move'" href="#">Move Resource
</a>
<a :class="activeTab === 'danger' && 'text-white'"
@click.prevent="activeTab = 'danger'; window.location.hash = 'danger'" href="#">Danger Zone
</a>
@@ -106,6 +108,9 @@
<div x-cloak x-show="activeTab === 'scheduled-tasks'">
<livewire:project.shared.scheduled-task.all :resource="$application" />
</div>
<div x-cloak x-show="activeTab === 'move'">
<livewire:project.shared.move-resource :resource="$application" />
</div>
<div x-cloak x-show="activeTab === 'danger'">
<livewire:project.shared.danger :resource="$application" />
</div>

View File

@@ -44,7 +44,9 @@
window.location.hash = 'resource-limits'"
href="#">Resource Limits
</a>
<a :class="activeTab === 'move' && 'text-white'"
@click.prevent="activeTab = 'move'; window.location.hash = 'move'" href="#">Move Resource
</a>
<a :class="activeTab === 'danger' && 'text-white'"
@click.prevent="activeTab = 'danger';
window.location.hash = 'danger'"
@@ -83,6 +85,9 @@
<div x-cloak x-show="activeTab === 'import'">
<livewire:project.database.import :resource="$database" />
</div>
<div x-cloak x-show="activeTab === 'move'">
<livewire:project.shared.move-resource :resource="$database" />
</div>
<div x-cloak x-show="activeTab === 'danger'">
<livewire:project.shared.danger :resource="$database" />
</div>

View File

@@ -43,132 +43,134 @@
@if ($environment->isEmpty())
<a href="{{ route('project.resource.create', ['project_uuid' => request()->route('project_uuid'), 'environment_name' => request()->route('environment_name')]) }} "
class="items-center justify-center box">+ Add New Resource</a>
@endif
<div x-data="searchComponent()">
<x-forms.input placeholder="Search for name, fqdn..." class="w-full" x-model="search" />
<div class="grid gap-2 pt-4 lg:grid-cols-2">
<template x-for="item in filteredApplications" :key="item.id">
<a class="relative box group" :href="item.hrefLink">
<div class="flex flex-col mx-6">
<div class="pb-2 font-bold text-white" x-text="item.name"></div>
<div class="description" x-text="item.description"></div>
<div class="description" x-text="item.fqdn"></div>
</div>
<template x-if="item.status.startsWith('running')">
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('exited')">
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('restarting')">
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
</template>
</a>
</template>
<template x-for="item in filteredPostgresqls" :key="item.id">
<a class="relative box group" :href="item.hrefLink">
<div class="flex flex-col mx-6">
<div class="font-bold text-white" x-text="item.name"></div>
<div class="description" x-text="item.description"></div>
</div>
<template x-if="item.status.startsWith('running')">
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('exited')">
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('restarting')">
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
</template>
</a>
</template>
<template x-for="item in filteredRedis" :key="item.id">
<a class="relative box group" :href="item.hrefLink">
<div class="flex flex-col mx-6">
<div class="font-bold text-white" x-text="item.name"></div>
<div class="description" x-text="item.description"></div>
</div>
<template x-if="item.status.startsWith('running')">
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('exited')">
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('restarting')">
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
</template>
</a>
</template>
<template x-for="item in filteredMongodbs" :key="item.id">
<a class="relative box group" :href="item.hrefLink">
<div class="flex flex-col mx-6">
<div class="font-bold text-white" x-text="item.name"></div>
<div class="description" x-text="item.description"></div>
</div>
<template x-if="item.status.startsWith('running')">
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('exited')">
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('restarting')">
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
</template>
</a>
</template>
<template x-for="item in filteredMysqls" :key="item.id">
<a class="relative box group" :href="item.hrefLink">
<div class="flex flex-col mx-6">
<div class="font-bold text-white" x-text="item.name"></div>
<div class="description" x-text="item.description"></div>
</div>
<template x-if="item.status.startsWith('running')">
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('exited')">
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('restarting')">
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
</template>
</a>
</template>
<template x-for="item in filteredMariadbs" :key="item.id">
<a class="relative box group" :href="item.hrefLink">
<div class="flex flex-col mx-6">
<div class="font-bold text-white" x-text="item.name"></div>
<div class="description" x-text="item.description"></div>
</div>
<template x-if="item.status.startsWith('running')">
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('exited')">
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('restarting')">
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
</template>
</a>
</template>
<template x-for="item in filteredServices" :key="item.id">
<a class="relative box group" :href="item.hrefLink">
<div class="flex flex-col mx-6">
<div class="font-bold text-white" x-text="item.name"></div>
<div class="description" x-text="item.description"></div>
</div>
<template x-if="item.status.startsWith('running')">
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('exited')">
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('degraded')">
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
</template>
</a>
</template>
@else
<div x-data="searchComponent()">
<x-forms.input placeholder="Search for name, fqdn..." class="w-full" x-model="search" />
<div class="grid gap-2 pt-4 lg:grid-cols-2">
<template x-for="item in filteredApplications" :key="item.id">
<a class="relative box group" :href="item.hrefLink">
<div class="flex flex-col mx-6">
<div class="pb-2 font-bold text-white" x-text="item.name"></div>
<div class="description" x-text="item.description"></div>
<div class="description" x-text="item.fqdn"></div>
</div>
<template x-if="item.status.startsWith('running')">
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('exited')">
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('restarting')">
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
</template>
</a>
</template>
<template x-for="item in filteredPostgresqls" :key="item.id">
<a class="relative box group" :href="item.hrefLink">
<div class="flex flex-col mx-6">
<div class="font-bold text-white" x-text="item.name"></div>
<div class="description" x-text="item.description"></div>
</div>
<template x-if="item.status.startsWith('running')">
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('exited')">
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('restarting')">
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
</template>
</a>
</template>
<template x-for="item in filteredRedis" :key="item.id">
<a class="relative box group" :href="item.hrefLink">
<div class="flex flex-col mx-6">
<div class="font-bold text-white" x-text="item.name"></div>
<div class="description" x-text="item.description"></div>
</div>
<template x-if="item.status.startsWith('running')">
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('exited')">
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('restarting')">
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
</template>
</a>
</template>
<template x-for="item in filteredMongodbs" :key="item.id">
<a class="relative box group" :href="item.hrefLink">
<div class="flex flex-col mx-6">
<div class="font-bold text-white" x-text="item.name"></div>
<div class="description" x-text="item.description"></div>
</div>
<template x-if="item.status.startsWith('running')">
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('exited')">
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('restarting')">
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
</template>
</a>
</template>
<template x-for="item in filteredMysqls" :key="item.id">
<a class="relative box group" :href="item.hrefLink">
<div class="flex flex-col mx-6">
<div class="font-bold text-white" x-text="item.name"></div>
<div class="description" x-text="item.description"></div>
</div>
<template x-if="item.status.startsWith('running')">
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('exited')">
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('restarting')">
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
</template>
</a>
</template>
<template x-for="item in filteredMariadbs" :key="item.id">
<a class="relative box group" :href="item.hrefLink">
<div class="flex flex-col mx-6">
<div class="font-bold text-white" x-text="item.name"></div>
<div class="description" x-text="item.description"></div>
</div>
<template x-if="item.status.startsWith('running')">
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('exited')">
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('restarting')">
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
</template>
</a>
</template>
<template x-for="item in filteredServices" :key="item.id">
<a class="relative box group" :href="item.hrefLink">
<div class="flex flex-col mx-6">
<div class="font-bold text-white" x-text="item.name"></div>
<div class="description" x-text="item.description"></div>
</div>
<template x-if="item.status.startsWith('running')">
<div class="absolute bg-success -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('exited')">
<div class="absolute bg-error -top-1 -left-1 badge badge-xs"></div>
</template>
<template x-if="item.status.startsWith('degraded')">
<div class="absolute bg-warning -top-1 -left-1 badge badge-xs"></div>
</template>
</a>
</template>
</div>
</div>
</div>
@endif
</div>
<script>

View File

@@ -26,6 +26,9 @@
<a :class="activeTab === 'webhooks' && 'text-white'"
@click.prevent="activeTab = 'webhooks'; window.location.hash = 'webhooks'" href="#">Webhooks
</a>
<a :class="activeTab === 'move' && 'text-white'"
@click.prevent="activeTab = 'move'; window.location.hash = 'move'" href="#">Move Resource
</a>
<a :class="activeTab === 'danger' && 'text-white'"
@click.prevent="activeTab = 'danger';
window.location.hash = 'danger'"
@@ -157,6 +160,9 @@
<div x-cloak x-show="activeTab === 'environment-variables'">
<livewire:project.shared.environment-variable.all :resource="$service" />
</div>
<div x-cloak x-show="activeTab === 'move'">
<livewire:project.shared.move-resource :resource="$service" />
</div>
<div x-cloak x-show="activeTab === 'danger'">
<livewire:project.shared.danger :resource="$service" />
</div>

View File

@@ -0,0 +1,25 @@
<div>
<h2>Move Resource</h2>
<div class="pb-4">You can easily move this resource to another project.</div>
<div>
<div class="pb-8">
This resource is currently in the <span
class="font-bold text-warning">{{ $resource->environment->project->name }} /
{{ $resource->environment->name }}</span> environment.
</div>
<div class="grid grid-flow-col grid-rows-2 gap-4">
@forelse ($projects as $project)
<div class="grid grid-flow-col grid-rows-2 gap-4">
@foreach ($project->environments as $environment)
<div class="flex flex-col gap-2 box" wire:click="moveTo('{{ data_get($environment, 'id') }}')">
<div class="font-bold text-white">{{ $project->name }}</div>
<div><span class="text-warning">{{ $environment->name }}</span> environment</div>
</div>
@endforeach
</div>
@empty
<div>No projects found to move to</div>
@endforelse
</div>
</div>
</div>