feat(servers): separate connection and provisioning options

Group existing server connections separately from cloud provisioning and use a select for dedicated build server roles.
This commit is contained in:
Andras Bacsai committed 2026-08-10 10:09:03 +02:00
1 parent faf527d554
commit 4ba6aa3500
5 files changed
+148 -105

No files matched your search

@@ -15,91 +15,89 @@
</div>
@if (!$selectedType)
<div class="application-settings-form">
<div class="application-settings-form flex flex-col gap-6">
<section class="application-settings-section">
<div class="application-settings-section-body is-flush">
<div class="grid grid-cols-1 gap-3 p-3 sm:grid-cols-2 lg:grid-cols-4">
@can('viewAny', App\Models\CloudProviderToken::class)
<a href="{{ route('server.create.type', ['type' => 'hetzner']) }}"
class="group flex min-h-32 flex-col rounded-xl border border-neutral-200 bg-white p-3 shadow-sm transition-all hover:-translate-y-px hover:border-neutral-300 hover:no-underline hover:shadow-md dark:border-white/[0.08] dark:bg-white/[0.025] dark:hover:border-white/[0.14]"
{{ wireNavigate() }}>
<div class="flex items-start justify-between gap-3">
<span
class="flex size-8 items-center justify-center rounded-lg bg-[#D50C2D] text-[12px] font-bold text-white">H</span>
<span
class="rounded-full bg-neutral-100 px-2 py-0.5 text-[10px] font-medium text-neutral-600 dark:bg-white/[0.06] dark:text-fg-dim">
Provider
</span>
</div>
<div class="mt-auto pt-5">
<h3 class="text-[13px]! font-semibold! text-black dark:text-fg">Hetzner</h3>
<p class="mt-1 text-[11px] leading-4 text-neutral-500 dark:text-fg-faint">
Provision from Hetzner Cloud.
</p>
</div>
</a>
<a href="{{ route('server.create.type', ['type' => 'vultr']) }}"
class="group flex min-h-32 flex-col rounded-xl border border-neutral-200 bg-white p-3 shadow-sm transition-all hover:-translate-y-px hover:border-neutral-300 hover:no-underline hover:shadow-md dark:border-white/[0.08] dark:bg-white/[0.025] dark:hover:border-white/[0.14]"
{{ wireNavigate() }}>
<div class="flex items-start justify-between gap-3">
<span
class="flex size-8 items-center justify-center rounded-lg bg-[#007BFC] text-[12px] font-bold text-white">V</span>
<span
class="rounded-full bg-neutral-100 px-2 py-0.5 text-[10px] font-medium text-neutral-600 dark:bg-white/[0.06] dark:text-fg-dim">
Provider
</span>
</div>
<div class="mt-auto pt-5">
<h3 class="text-[13px]! font-semibold! text-black dark:text-fg">Vultr</h3>
<p class="mt-1 text-[11px] leading-4 text-neutral-500 dark:text-fg-faint">
Provision from Vultr Cloud.
</p>
</div>
</a>
<a href="{{ route('server.create.type', ['type' => 'digital-ocean']) }}"
class="group flex min-h-32 flex-col rounded-xl border border-neutral-200 bg-white p-3 shadow-sm transition-all hover:-translate-y-px hover:border-neutral-300 hover:no-underline hover:shadow-md dark:border-white/[0.08] dark:bg-white/[0.025] dark:hover:border-white/[0.14]"
{{ wireNavigate() }}>
<div class="flex items-start justify-between gap-3">
<x-digital-ocean-icon class="size-8" />
<span
class="rounded-full bg-neutral-100 px-2 py-0.5 text-[10px] font-medium text-neutral-600 dark:bg-white/[0.06] dark:text-fg-dim">
Provider
</span>
</div>
<div class="mt-auto pt-5">
<h3 class="text-[13px]! font-semibold! text-black dark:text-fg">DigitalOcean</h3>
<p class="mt-1 text-[11px] leading-4 text-neutral-500 dark:text-fg-faint">
Provision a new Droplet.
</p>
</div>
</a>
@endcan
<a href="{{ route('server.create.type', ['type' => 'manual']) }}"
class="group flex min-h-32 flex-col rounded-xl border border-neutral-200 bg-white p-3 shadow-sm transition-all hover:-translate-y-px hover:border-neutral-300 hover:no-underline hover:shadow-md dark:border-white/[0.08] dark:bg-white/[0.025] dark:hover:border-white/[0.14]"
{{ wireNavigate() }}>
<div class="flex items-start justify-between gap-3">
<span
class="flex size-8 items-center justify-center rounded-lg border border-neutral-200 bg-neutral-50 text-neutral-500 dark:border-white/[0.08] dark:bg-white/[0.04] dark:text-fg-dim">
<x-reicon name="servers" class="size-4" />
</span>
<span
class="rounded-full bg-neutral-100 px-2 py-0.5 text-[10px] font-medium text-neutral-600 dark:bg-white/[0.06] dark:text-fg-dim">
Manual
</span>
</div>
<div class="mt-auto pt-5">
<h3 class="text-[13px]! font-semibold! text-black dark:text-fg">IP address</h3>
<p class="mt-1 text-[11px] leading-4 text-neutral-500 dark:text-fg-faint">
Connect an existing server over SSH.
</p>
</div>
</a>
<div class="application-settings-section-header">
<h2 class="application-settings-section-title">Add a server</h2>
<p class="application-settings-section-description">Connect a server you already manage.</p>
</div>
<div class="application-settings-section-body is-flush">
<div class="grid grid-cols-1 gap-3 p-3 sm:grid-cols-2 lg:grid-cols-4">
<a href="{{ route('server.create.type', ['type' => 'manual']) }}"
class="group flex min-h-32 flex-col rounded-xl border border-neutral-200 bg-white p-3 shadow-sm transition-all hover:-translate-y-px hover:border-neutral-300 hover:no-underline hover:shadow-md dark:border-white/[0.08] dark:bg-white/[0.025] dark:hover:border-white/[0.14]"
{{ wireNavigate() }}>
<div class="flex items-start">
<span
class="flex size-8 items-center justify-center rounded-lg border border-neutral-200 bg-neutral-50 text-neutral-500 dark:border-white/[0.08] dark:bg-white/[0.04] dark:text-fg-dim">
<x-reicon name="servers" class="size-4" />
</span>
</div>
<div class="mt-auto pt-5">
<h3 class="text-[13px]! font-semibold! text-black dark:text-fg">IP address or domain</h3>
<p class="mt-1 text-[11px] leading-4 text-neutral-500 dark:text-fg-faint">
Connect an existing server over SSH.
</p>
</div>
</a>
</div>
</div>
</section>
@can('viewAny', App\Models\CloudProviderToken::class)
<section class="application-settings-section">
<div class="application-settings-section-header">
<h2 class="application-settings-section-title">Provision a server</h2>
<p class="application-settings-section-description">Create a server with a cloud provider.</p>
</div>
<div class="application-settings-section-body is-flush">
<div class="grid grid-cols-1 gap-3 p-3 sm:grid-cols-2 lg:grid-cols-3">
<a href="{{ route('server.create.type', ['type' => 'hetzner']) }}"
class="group flex min-h-32 flex-col rounded-xl border border-neutral-200 bg-white p-3 shadow-sm transition-all hover:-translate-y-px hover:border-neutral-300 hover:no-underline hover:shadow-md dark:border-white/[0.08] dark:bg-white/[0.025] dark:hover:border-white/[0.14]"
{{ wireNavigate() }}>
<div class="flex items-start">
<img src="{{ asset('svgs/hetzner.svg') }}" alt="Hetzner" class="size-8">
</div>
<div class="mt-auto pt-5">
<h3 class="text-[13px]! font-semibold! text-black dark:text-fg">Hetzner</h3>
<p class="mt-1 text-[11px] leading-4 text-neutral-500 dark:text-fg-faint">
Provision from Hetzner Cloud.
</p>
</div>
</a>
<a href="{{ route('server.create.type', ['type' => 'vultr']) }}"
class="group flex min-h-32 flex-col rounded-xl border border-neutral-200 bg-white p-3 shadow-sm transition-all hover:-translate-y-px hover:border-neutral-300 hover:no-underline hover:shadow-md dark:border-white/[0.08] dark:bg-white/[0.025] dark:hover:border-white/[0.14]"
{{ wireNavigate() }}>
<div class="flex items-start">
<img src="https://www.vultr.com/media/logo_ondark.svg" alt="Vultr"
class="h-8 w-20 object-contain object-left">
</div>
<div class="mt-auto pt-5">
<h3 class="text-[13px]! font-semibold! text-black dark:text-fg">Vultr</h3>
<p class="mt-1 text-[11px] leading-4 text-neutral-500 dark:text-fg-faint">
Provision from Vultr Cloud.
</p>
</div>
</a>
<a href="{{ route('server.create.type', ['type' => 'digital-ocean']) }}"
class="group flex min-h-32 flex-col rounded-xl border border-neutral-200 bg-white p-3 shadow-sm transition-all hover:-translate-y-px hover:border-neutral-300 hover:no-underline hover:shadow-md dark:border-white/[0.08] dark:bg-white/[0.025] dark:hover:border-white/[0.14]"
{{ wireNavigate() }}>
<div class="flex items-start">
<x-digital-ocean-icon class="size-8" />
</div>
<div class="mt-auto pt-5">
<h3 class="text-[13px]! font-semibold! text-black dark:text-fg">DigitalOcean</h3>
<p class="mt-1 text-[11px] leading-4 text-neutral-500 dark:text-fg-faint">
Provision a new Droplet.
</p>
</div>
</a>
</div>
</div>
</section>
@endcan
</div>
@else
<div class="application-settings-form">