New onboarding error UI and advanced menu

This commit is contained in:
peaklabs-dev
2024-09-10 13:55:58 +02:00
parent 435c0baa87
commit f3845ce30a

View File

@@ -1,20 +1,18 @@
@php use App\Enums\ProxyTypes; @endphp @php use App\Enums\ProxyTypes; @endphp
<x-slot:title> <x-slot:title>
Onboarding | Coolify Onboarding | Coolify
</x-slot> </x-slot>
<section class="flex flex-col h-full lg:items-center lg:justify-center"> <section class="flex flex-col h-full lg:items-center lg:justify-center">
<div <div class="flex flex-col items-center justify-center p-10 mx-2 mt-10 bg-white border rounded-lg shadow lg:p-20 dark:bg-transparent dark:border-none max-w-7xl ">
class="flex flex-col items-center justify-center p-10 mx-2 mt-10 bg-white border rounded-lg shadow lg:p-20 dark:bg-transparent dark:border-none max-w-7xl "> @if ($currentState === 'welcome')
@if ($currentState === 'welcome')
<h1 class="text-3xl font-bold lg:text-5xl">Welcome to Coolify</h1> <h1 class="text-3xl font-bold lg:text-5xl">Welcome to Coolify</h1>
<div class="py-6 text-center lg:text-xl">Let me help you set up the basics.</div> <div class="py-6 text-center lg:text-xl">Let me help you set up the basics.</div>
<div class="flex justify-center "> <div class="flex justify-center ">
<x-forms.button class="justify-center w-64 box-boarding" <x-forms.button class="justify-center w-64 box-boarding" wire:click="$set('currentState','explanation')">Get
wire:click="$set('currentState','explanation')">Get
Started Started
</x-forms.button> </x-forms.button>
</div> </div>
@elseif ($currentState === 'explanation') @elseif ($currentState === 'explanation')
<x-boarding-step title="What is Coolify?"> <x-boarding-step title="What is Coolify?">
<x-slot:question> <x-slot:question>
Coolify is an all-in-one application to automate tasks on your servers, deploy application with Coolify is an all-in-one application to automate tasks on your servers, deploy application with
@@ -28,12 +26,15 @@
<x-highlighted text="Self-hosting with superpowers!" /></span> <x-highlighted text="Self-hosting with superpowers!" /></span>
</x-slot:question> </x-slot:question>
<x-slot:explanation> <x-slot:explanation>
<p><x-highlighted text="Task automation:" /> You don't need to manage your servers anymore. <p>
<x-highlighted text="Task automation:" /> You don't need to manage your servers anymore.
Coolify does Coolify does
it for you.</p> it for you.</p>
<p><x-highlighted text="No vendor lock-in:" /> All configurations are stored on your servers, so <p>
<x-highlighted text="No vendor lock-in:" /> All configurations are stored on your servers, so
everything works without a connection to Coolify (except integrations and automations).</p> everything works without a connection to Coolify (except integrations and automations).</p>
<p><x-highlighted text="Monitoring:" />You can get notified on your favourite platforms <p>
<x-highlighted text="Monitoring:" />You can get notified on your favourite platforms
(Discord, (Discord,
Telegram, Email, etc.) when something goes wrong, or an action is needed from your side.</p> Telegram, Email, etc.) when something goes wrong, or an action is needed from your side.</p>
</x-slot:explanation> </x-slot:explanation>
@@ -42,70 +43,91 @@
</x-forms.button> </x-forms.button>
</x-slot:actions> </x-slot:actions>
</x-boarding-step> </x-boarding-step>
@elseif ($currentState === 'select-server-type') @elseif ($currentState === 'select-server-type')
<x-boarding-step title="Server"> <x-boarding-step title="Server">
<x-slot:question> <x-slot:question>
Do you want to deploy your resources to your <x-highlighted text="Localhost" /> Do you want to deploy your resources to your
or to a <x-highlighted text="Remote Server" />? <x-highlighted text="Localhost" />
or to a
<x-highlighted text="Remote Server" />?
</x-slot:question> </x-slot:question>
<x-slot:actions> <x-slot:actions>
<x-forms.button class="justify-center w-64 box-boarding" wire:target="setServerType('localhost')" <x-forms.button class="justify-center w-64 box-boarding" wire:target="setServerType('localhost')" wire:click="setServerType('localhost')">Localhost
wire:click="setServerType('localhost')">Localhost
</x-forms.button> </x-forms.button>
<x-forms.button class="justify-center w-64 box-boarding " wire:target="setServerType('remote')" <x-forms.button class="justify-center w-64 box-boarding " wire:target="setServerType('remote')" wire:click="setServerType('remote')">Remote Server
wire:click="setServerType('remote')">Remote Server
</x-forms.button> </x-forms.button>
@if (!$serverReachable) @if (!$serverReachable)
Localhost is not reachable with the following public key. <div class="mt-6 p-4 bg-red-100 dark:bg-red-950 rounded-lg text-gray-800 dark:text-gray-200">
<br /> <br /> <h2 class="text-lg font-bold mb-2">Server is not reachable</h2>
Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for <p class="mb-4">Please check the connection details below and correct them if they are incorrect.</p>
user or skip the boarding process and add a new private key manually to Coolify and to the
server. <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<br /> <x-forms.input placeholder="Default is 22" label="Port" id="remoteServerPort" wire:model="remoteServerPort" value="{{ $createdServer->port }}" />
Check this <a target="_blank" class="underline" <div>
href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further <x-forms.input placeholder="Default is root" label="User" id="remoteServerUser" wire:model="remoteServerUser" value="{{ $createdServer->user }}" />
help. <p class="text-xs mt-1">
<x-forms.input readonly id="serverPublicKey"></x-forms.input> Non-root user is experimental:
<x-forms.button class="lg:w-64 box-boarding" wire:target="setServerType('localhost')" <a class="font-bold underline" target="_blank" href="https://coolify.io/docs/knowledge-base/server/non-root-user">docs</a>
wire:click="setServerType('localhost')">Check again </p>
</div>
</div>
<div class="mb-4">
<p class="mb-2">If the connection details are correct, please ensure:</p>
<ul class="list-disc list-inside">
<li>The correct public key is in your <code class="bg-red-200 dark:bg-red-900 px-1 rounded">~/.ssh/authorized_keys</code> file for the specified user</li>
<li>Or skip the boarding process and manually add a new private key to Coolify and the server</li>
</ul>
</div>
<p class="mb-4">
For more help, check this <a target="_blank" class="underline font-semibold" href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a>.
</p>
<x-forms.input readonly id="serverPublicKey" class="mb-4" label="Current Public Key"></x-forms.input>
<x-forms.button class="w-full md:w-auto box-boarding" wire:target="setServerType('localhost')" wire:click="setServerType('localhost')">
Check again
</x-forms.button> </x-forms.button>
</div>
@endif @endif
</x-slot:actions> </x-slot:actions>
<x-slot:explanation> <x-slot:explanation>
<p>Servers are the main building blocks, as they will host your applications, databases, <p>Servers are the main building blocks, as they will host your applications, databases,
services, called resources. Any CPU intensive process will use the server's CPU where you services, called resources. Any CPU intensive process will use the server's CPU where you
are deploying your resources.</p> are deploying your resources.</p>
<p><x-highlighted text="Localhost" /> is the server where Coolify is running on. It is not <p>
<x-highlighted text="Localhost" /> is the server where Coolify is running on. It is not
recommended to use one server recommended to use one server
for everything.</p> for everything.</p>
<p><x-highlighted text="A remote server" /> is a server reachable through SSH. It can be hosted <p>
<x-highlighted text="A remote server" /> is a server reachable through SSH. It can be hosted
at home, or from any cloud at home, or from any cloud
provider.</p> provider.</p>
</x-slot:explanation> </x-slot:explanation>
</x-boarding-step> </x-boarding-step>
@elseif ($currentState === 'private-key') @elseif ($currentState === 'private-key')
<x-boarding-step title="SSH Key"> <x-boarding-step title="SSH Key">
<x-slot:question> <x-slot:question>
Do you have your own SSH Private Key? Do you have your own SSH Private Key?
</x-slot:question> </x-slot:question>
<x-slot:actions> <x-slot:actions>
<x-forms.button class="justify-center lg:w-64 box-boarding" wire:target="setPrivateKey('own')" <x-forms.button class="justify-center lg:w-64 box-boarding" wire:target="setPrivateKey('own')" wire:click="setPrivateKey('own')">Yes
wire:click="setPrivateKey('own')">Yes
</x-forms.button> </x-forms.button>
<x-forms.button class="justify-center lg:w-64 box-boarding" wire:target="setPrivateKey('create')" <x-forms.button class="justify-center lg:w-64 box-boarding" wire:target="setPrivateKey('create')" wire:click="setPrivateKey('create')">No (create one for me)
wire:click="setPrivateKey('create')">No (create one for me)
</x-forms.button> </x-forms.button>
@if (count($privateKeys) > 0) @if (count($privateKeys) > 0)
<form wire:submit='selectExistingPrivateKey' class="flex flex-col w-full gap-4 lg:pr-10"> <form wire:submit='selectExistingPrivateKey' class="flex flex-col w-full gap-4 lg:pr-10">
<x-forms.select label="Existing SSH Keys" id='selectedExistingPrivateKey'> <x-forms.select label="Existing SSH Keys" id='selectedExistingPrivateKey'>
@foreach ($privateKeys as $privateKey) @foreach ($privateKeys as $privateKey)
<option wire:key="{{ $loop->index }}" value="{{ $privateKey->id }}"> <option wire:key="{{ $loop->index }}" value="{{ $privateKey->id }}">
{{ $privateKey->name }}</option> {{ $privateKey->name }}</option>
@endforeach @endforeach
</x-forms.select> </x-forms.select>
<x-forms.button type="submit">Use this SSH Key</x-forms.button> <x-forms.button type="submit">Use this SSH Key</x-forms.button>
</form> </form>
@endif @endif
</x-slot:actions> </x-slot:actions>
<x-slot:explanation> <x-slot:explanation>
@@ -117,7 +139,7 @@
</p> </p>
</x-slot:explanation> </x-slot:explanation>
</x-boarding-step> </x-boarding-step>
@elseif ($currentState === 'select-existing-server') @elseif ($currentState === 'select-existing-server')
<x-boarding-step title="Select a server"> <x-boarding-step title="Select a server">
<x-slot:question> <x-slot:question>
There are already servers available for your Team. Do you want to use one of them? There are already servers available for your Team. Do you want to use one of them?
@@ -136,8 +158,8 @@
<form wire:submit='selectExistingServer' class="flex flex-col w-full gap-4 lg:w-96"> <form wire:submit='selectExistingServer' class="flex flex-col w-full gap-4 lg:w-96">
<x-forms.select label="Existing servers" class="w-96" id='selectedExistingServer'> <x-forms.select label="Existing servers" class="w-96" id='selectedExistingServer'>
@foreach ($servers as $server) @foreach ($servers as $server)
<option wire:key="{{ $loop->index }}" value="{{ $server->id }}"> <option wire:key="{{ $loop->index }}" value="{{ $server->id }}">
{{ $server->name }}</option> {{ $server->name }}</option>
@endforeach @endforeach
</x-forms.select> </x-forms.select>
<x-forms.button type="submit">Use this Server</x-forms.button> <x-forms.button type="submit">Use this Server</x-forms.button>
@@ -145,20 +167,18 @@
</div> </div>
</div> </div>
@if (!$serverReachable) @if (!$serverReachable)
This server is not reachable with the following public key. This server is not reachable with the following public key.
<br /> <br /> <br /> <br />
Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for
user or skip the boarding process and add a new private key manually to Coolify and to the user or skip the boarding process and add a new private key manually to Coolify and to the
server. server.
<br /> <br />
Check this <a target="_blank" class="underline" Check this <a target="_blank" class="underline" href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further
href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further help.
help. <x-forms.input readonly id="serverPublicKey"></x-forms.input>
<x-forms.input readonly id="serverPublicKey"></x-forms.input> <x-forms.button class="w-64 box-boarding" wire:target="validateServer" wire:click="validateServer">Check
<x-forms.button class="w-64 box-boarding" wire:target="validateServer" again
wire:click="validateServer">Check </x-forms.button>
again
</x-forms.button>
@endif @endif
</x-slot:actions> </x-slot:actions>
<x-slot:explanation> <x-slot:explanation>
@@ -169,25 +189,22 @@
</p> </p>
</x-slot:explanation> </x-slot:explanation>
</x-boarding-step> </x-boarding-step>
@elseif ($currentState === 'create-private-key') @elseif ($currentState === 'create-private-key')
<x-boarding-step title="Create Private Key"> <x-boarding-step title="Create Private Key">
<x-slot:question> <x-slot:question>
Please let me know your key details. Please let me know your key details.
</x-slot:question> </x-slot:question>
<x-slot:actions> <x-slot:actions>
<form wire:submit='savePrivateKey' class="flex flex-col w-full gap-4 lg:pr-10"> <form wire:submit='savePrivateKey' class="flex flex-col w-full gap-4 lg:pr-10">
<x-forms.input required placeholder="Choose a name for your Private Key. Could be anything." <x-forms.input required placeholder="Choose a name for your Private Key. Could be anything." label="Name" id="privateKeyName" />
label="Name" id="privateKeyName" /> <x-forms.input placeholder="Description, so others will know more about this." label="Description" id="privateKeyDescription" />
<x-forms.input placeholder="Description, so others will know more about this." <x-forms.textarea required placeholder="-----BEGIN OPENSSH PRIVATE KEY-----" label="Private Key" id="privateKey" />
label="Description" id="privateKeyDescription" />
<x-forms.textarea required placeholder="-----BEGIN OPENSSH PRIVATE KEY-----" label="Private Key"
id="privateKey" />
@if ($privateKeyType === 'create') @if ($privateKeyType === 'create')
<x-forms.textarea rows="7" readonly label="Public Key" id="publicKey" /> <x-forms.textarea rows="7" readonly label="Public Key" id="publicKey" />
<span class="font-bold dark:text-warning">ACTION REQUIRED: Copy the 'Public Key' to your <span class="font-bold dark:text-warning">ACTION REQUIRED: Copy the 'Public Key' to your
server's server's
~/.ssh/authorized_keys ~/.ssh/authorized_keys
file.</span> file.</span>
@endif @endif
<x-forms.button type="submit">Save</x-forms.button> <x-forms.button type="submit">Save</x-forms.button>
</form> </form>
@@ -200,7 +217,7 @@
</p> </p>
</x-slot:explanation> </x-slot:explanation>
</x-boarding-step> </x-boarding-step>
@elseif ($currentState === 'create-server') @elseif ($currentState === 'create-server')
<x-boarding-step title="Create Server"> <x-boarding-step title="Create Server">
<x-slot:question> <x-slot:question>
Please let me know your server details. Please let me know your server details.
@@ -208,34 +225,33 @@
<x-slot:actions> <x-slot:actions>
<form wire:submit='saveServer' class="flex flex-col w-full gap-4 lg:pr-10"> <form wire:submit='saveServer' class="flex flex-col w-full gap-4 lg:pr-10">
<div class="flex flex-col gap-2 lg:flex-row"> <div class="flex flex-col gap-2 lg:flex-row">
<x-forms.input required placeholder="Choose a name for your Server. Could be anything." <x-forms.input required placeholder="Choose a name for your Server. Could be anything." label="Name" id="remoteServerName" />
label="Name" id="remoteServerName" /> <x-forms.input placeholder="Description, so others will know more about this." label="Description" id="remoteServerDescription" />
<x-forms.input placeholder="Description, so others will know more about this."
label="Description" id="remoteServerDescription" />
</div> </div>
<div class="flex flex-col gap-2 lg:flex-row "> <div class="flex flex-col gap-2 lg:flex-row ">
<x-forms.input required placeholder="127.0.0.1" label="IP Address" id="remoteServerHost" /> <x-forms.input required placeholder="127.0.0.1" label="IP Address" id="remoteServerHost" />
<x-forms.input required placeholder="Port number of your server. Default is 22." </div>
label="Port" id="remoteServerPort" /> <div x-data="{ showAdvanced: false }" class="flex flex-col gap-2">
<div class="w-full"> <button @click="showAdvanced = !showAdvanced" type="button" class="text-left text-sm text-gray-600 dark:text-gray-300 hover:underline">
<x-forms.input required placeholder="User to connect to your server. Default is root." Advanced Settings
label="User" id="remoteServerUser" /> </button>
<div class="text-xs dark:text-warning text-coollabs ">Non-root user is experimental: <a <div x-show="showAdvanced" class="flex flex-col gap-2 lg:flex-row">
class="font-bold underline" target="_blank" <x-forms.input placeholder="Port number of your server. Default is 22." label="Port" id="remoteServerPort" wire:model="remoteServerPort" />
href="https://coolify.io/docs/knowledge-base/server/non-root-user">docs</a>. <div class="w-full">
<x-forms.input placeholder="User to connect to your server. Default is root." label="User" id="remoteServerUser" wire:model="remoteServerUser" />
<div class="text-xs text-gray-600 dark:text-gray-300">Non-root user is experimental: <a class="font-bold underline" target="_blank" href="https://coolify.io/docs/knowledge-base/server/non-root-user">docs</a>.
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="lg:w-64"> <div class="lg:w-64">
<x-forms.checkbox <x-forms.checkbox helper="If you are using Cloudflare Tunnels, enable this. It will proxy all ssh requests to your server through Cloudflare.<br><span class='dark:text-warning'>Coolify does not install/setup Cloudflare (cloudflared) on your server.</span>" id="isCloudflareTunnel" label="Cloudflare Tunnel" />
helper="If you are using Cloudflare Tunnels, enable this. It will proxy all ssh requests to your server through Cloudflare.<br><span class='dark:text-warning'>Coolify does not install/setup Cloudflare (cloudflared) on your server.</span>"
id="isCloudflareTunnel" label="Cloudflare Tunnel" />
</div> </div>
<x-forms.button type="submit">Continue</x-forms.button> <x-forms.button type="submit">Continue</x-forms.button>
</form> </form>
</x-slot:actions> </x-slot:actions>
</x-boarding-step> </x-boarding-step>
@elseif ($currentState === 'validate-server') @elseif ($currentState === 'validate-server')
<x-boarding-step title="Validate & Configure Server"> <x-boarding-step title="Validate & Configure Server">
<x-slot:question> <x-slot:question>
I need to validate your server (connection, Docker Engine, etc) and configure if something is I need to validate your server (connection, Docker Engine, etc) and configure if something is
@@ -247,8 +263,7 @@
<x-slot:content> <x-slot:content>
<livewire:server.validate-and-install :server="$this->createdServer" /> <livewire:server.validate-and-install :server="$this->createdServer" />
</x-slot:content> </x-slot:content>
<x-forms.button @click="slideOverOpen=true" class="w-full font-bold box-boarding lg:w-96" <x-forms.button @click="slideOverOpen=true" class="w-full font-bold box-boarding lg:w-96" wire:click.prevent='installServer' isHighlighted>
wire:click.prevent='installServer' isHighlighted>
Let's do it! Let's do it!
</x-forms.button> </x-forms.button>
</x-slide-over> </x-slide-over>
@@ -257,20 +272,19 @@
<p>This will install the latest Docker Engine on your server, configure a few things to be able <p>This will install the latest Docker Engine on your server, configure a few things to be able
to run optimal.<br><br>Minimum Docker Engine version is: 22<br><br>To manually install to run optimal.<br><br>Minimum Docker Engine version is: 22<br><br>To manually install
Docker Docker
Engine, check <a target="_blank" class="underline dark:text-warning" Engine, check <a target="_blank" class="underline dark:text-warning" href="https://docs.docker.com/engine/install/#server">this
href="https://docs.docker.com/engine/install/#server">this
documentation</a>.</p> documentation</a>.</p>
</x-slot:explanation> </x-slot:explanation>
</x-boarding-step> </x-boarding-step>
@elseif ($currentState === 'create-project') @elseif ($currentState === 'create-project')
<x-boarding-step title="Project"> <x-boarding-step title="Project">
<x-slot:question> <x-slot:question>
@if (count($projects) > 0) @if (count($projects) > 0)
You already have some projects. Do you want to use one of them or should I create a new one You already have some projects. Do you want to use one of them or should I create a new one
for for
you? you?
@else @else
Let's create an initial project for you. You can change all the details later on. Let's create an initial project for you. You can change all the details later on.
@endif @endif
</x-slot:question> </x-slot:question>
<x-slot:actions> <x-slot:actions>
@@ -278,15 +292,15 @@
project!</x-forms.button> project!</x-forms.button>
<div> <div>
@if (count($projects) > 0) @if (count($projects) > 0)
<form wire:submit='selectExistingProject' class="flex flex-col w-full gap-4 lg:w-96"> <form wire:submit='selectExistingProject' class="flex flex-col w-full gap-4 lg:w-96">
<x-forms.select label="Existing projects" class="w-96" id='selectedProject'> <x-forms.select label="Existing projects" class="w-96" id='selectedProject'>
@foreach ($projects as $project) @foreach ($projects as $project)
<option wire:key="{{ $loop->index }}" value="{{ $project->id }}"> <option wire:key="{{ $loop->index }}" value="{{ $project->id }}">
{{ $project->name }}</option> {{ $project->name }}</option>
@endforeach @endforeach
</x-forms.select> </x-forms.select>
<x-forms.button type="submit">Use this Project</x-forms.button> <x-forms.button type="submit">Use this Project</x-forms.button>
</form> </form>
@endif @endif
</div> </div>
</x-slot:actions> </x-slot:actions>
@@ -297,7 +311,7 @@
staging version of the same application, but grouped separately.</p> staging version of the same application, but grouped separately.</p>
</x-slot:explanation> </x-slot:explanation>
</x-boarding-step> </x-boarding-step>
@elseif ($currentState === 'create-resource') @elseif ($currentState === 'create-resource')
<x-boarding-step title="Resources"> <x-boarding-step title="Resources">
<x-slot:question> <x-slot:question>
Let's go to the new resource page, where you can create your first resource. Let's go to the new resource page, where you can create your first resource.
@@ -310,24 +324,23 @@
<p>A resource could be an application, a database or a service (like WordPress).</p> <p>A resource could be an application, a database or a service (like WordPress).</p>
</x-slot:explanation> </x-slot:explanation>
</x-boarding-step> </x-boarding-step>
@endif @endif
</div>
<div class="flex flex-col justify-center gap-4 pt-4 lg:gap-2 lg:flex">
<div class="flex justify-center w-full gap-2">
<div class="cursor-pointer hover:underline dark:hover:text-white" wire:click='skipBoarding'>Skip
onboarding</div>
<div class="cursor-pointer hover:underline dark:hover:text-white" wire:click='restartBoarding'>Restart
onboarding</div>
</div> </div>
<x-modal-input title="How can we help?"> <div class="flex flex-col justify-center gap-4 pt-4 lg:gap-2 lg:flex">
<x-slot:content> <div class="flex justify-center w-full gap-2">
<div class="w-full text-center cursor-pointer hover:underline dark:hover:text-white" <div class="cursor-pointer hover:underline dark:hover:text-white" wire:click='skipBoarding'>Skip
title="Send us feedback or get help!"> onboarding</div>
Feedback <div class="cursor-pointer hover:underline dark:hover:text-white" wire:click='restartBoarding'>Restart
</div> onboarding</div>
</x-slot:content> </div>
<livewire:help /> <x-modal-input title="How can we help?">
</x-modal-input> <x-slot:content>
</div> <div class="w-full text-center cursor-pointer hover:underline dark:hover:text-white" title="Send us feedback or get help!">
</div> Feedback
</section> </div>
</x-slot:content>
<livewire:help />
</x-modal-input>
</div>
</div>
</section>