This commit is contained in:
Andras Bacsai 2023-05-16 10:03:34 +02:00
parent e54369334b
commit 9cff545c99
5 changed files with 83 additions and 18 deletions

View File

@ -29,6 +29,9 @@ class ByIp extends Component
public function mount() public function mount()
{ {
$this->name = generateRandomName(); $this->name = generateRandomName();
if ($this->private_keys->count() > 0) {
$this->private_key_id = $this->private_keys->first()->id;
}
} }
public function setPrivateKey(string $private_key_id) public function setPrivateKey(string $private_key_id)
{ {

View File

@ -14,6 +14,7 @@ public function up(): void
Schema::create('server_settings', function (Blueprint $table) { Schema::create('server_settings', function (Blueprint $table) {
$table->id(); $table->id();
$table->string('uuid')->unique(); $table->string('uuid')->unique();
$table->boolean('is_jump_server')->default(false);
$table->boolean('is_build_server')->default(false); $table->boolean('is_build_server')->default(false);
$table->boolean('is_validated')->default(false); $table->boolean('is_validated')->default(false);

View File

@ -166,6 +166,30 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
</div> </div>
</div> </div>
</template> </template>
{{-- Private Keys --}}
<template x-cloak x-if="privateKeysMenu">
<div x-on:click.outside="closeMenus">
<input x-ref="search" x-model="search" class="magic-input" placeholder="Select a private key..."
x-on:keyup.escape="closeMenus" x-on:keydown.down="focusNext(privateKeys.length)"
x-on:keydown.up="focusPrev(privateKeys.length)"
x-on:keyup.enter="focusedIndex !== '' && await set('jumpToPrivateKey',filteredPrivateKeys()[focusedIndex].uuid)" />
<div class="magic-items">
<template x-if="privateKeys.length === 0">
<div class="magic-item" x-on:click="set('newPrivateKey')">
<span>No private key found. Click here to add a new one!</span>
</div>
</template>
<template x-for="(privateKey,index) in filteredPrivateKeys" :key="privateKey.name ?? privateKey">
<div x-on:click="await set('jumpToPrivateKey',privateKey.uuid)"
:class="focusedIndex === index && 'magic-item-focused'"
class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
<span class="px-2 mr-1 text-xs bg-purple-700 rounded">Jump</span>
<span x-text="privateKey.name"></span>
</div>
</template>
</div>
</div>
</template>
</div> </div>
<script> <script>
@ -177,7 +201,8 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
!this.projectMenu && !this.projectMenu &&
!this.environmentMenu && !this.environmentMenu &&
!this.projectsMenu && !this.projectsMenu &&
!this.destinationsMenu !this.destinationsMenu &&
!this.privateKeysMenu
}, },
focus() { focus() {
if (this.$refs.search) this.$refs.search.focus() if (this.$refs.search) this.$refs.search.focus()
@ -201,6 +226,9 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
this.$watch('environmentMenu', () => { this.$watch('environmentMenu', () => {
this.focus() this.focus()
}) })
this.$watch('privateKeysMenu', () => {
this.focus()
})
}, },
mainMenu: false, mainMenu: false,
serverMenu: false, serverMenu: false,
@ -209,6 +237,7 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
projectMenu: false, projectMenu: false,
projectsMenu: false, projectsMenu: false,
environmentMenu: false, environmentMenu: false,
privateKeysMenu: false,
search: '', search: '',
selectedAction: '', selectedAction: '',
@ -221,6 +250,7 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
destinations: ['Loading...'], destinations: ['Loading...'],
projects: ['Loading...'], projects: ['Loading...'],
environments: ['Loading...'], environments: ['Loading...'],
privateKeys: ['Loading...'],
focusedIndex: "", focusedIndex: "",
items: [{ items: [{
@ -286,6 +316,12 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
type: 'Jump', type: 'Jump',
tags: 'destinations', tags: 'destinations',
next: 'destinations' next: 'destinations'
},
{
name: 'Private Keys',
type: 'Jump',
tags: 'private keys,ssh, keys, key',
next: 'privateKeys'
} }
], ],
focusPrev(maxLength) { focusPrev(maxLength) {
@ -367,6 +403,13 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
.toLowerCase()) .toLowerCase())
}) })
}, },
filteredPrivateKeys() {
if (this.search === '') return this.privateKeys
return this.privateKeys.filter(privateKey => {
return privateKey.name.toLowerCase().includes(this.search
.toLowerCase())
})
},
async newProject() { async newProject() {
const response = await fetch('/magic?server=' + this.selectedServer + const response = await fetch('/magic?server=' + this.selectedServer +
'&destination=' + this.selectedDestination + '&destination=' + this.selectedDestination +
@ -465,6 +508,17 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
this.closeMenus() this.closeMenus()
this.destinationsMenu = true this.destinationsMenu = true
break break
case 'privateKeys':
response = await fetch('/magic?privateKeys=true');
if (response.ok) {
const {
privateKeys
} = await response.json();
this.privateKeys = privateKeys;
}
this.closeMenus()
this.privateKeysMenu = true
break
case 'environment': case 'environment':
if (this.focusedIndex === 0) { if (this.focusedIndex === 0) {
this.focusedIndex = '' this.focusedIndex = ''
@ -472,7 +526,6 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
} }
this.selectedProject = id this.selectedProject = id
response = await fetch('/magic?server=' + this response = await fetch('/magic?server=' + this
.selectedServer + .selectedServer +
'&destination=' + this.selectedDestination + '&destination=' + this.selectedDestination +
@ -494,7 +547,6 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
return await this.newEnvironment() return await this.newEnvironment()
} }
this.selectedEnvironment = id this.selectedEnvironment = id
console.log(this.selectedAction)
if (this.selectedAction === 0) { if (this.selectedAction === 0) {
window.location = window.location =
`/project/${this.selectedProject}/${this.selectedEnvironment}/new?type=public&destination=${this.selectedDestination}` `/project/${this.selectedProject}/${this.selectedEnvironment}/new?type=public&destination=${this.selectedDestination}`
@ -517,6 +569,10 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
window.location = `/destination/${id}` window.location = `/destination/${id}`
this.closeMenus() this.closeMenus()
break break
case 'jumpToPrivateKey':
window.location = `/private-key/${id}`
this.closeMenus()
break
case 'newServer': case 'newServer':
window.location = `/server/new` window.location = `/server/new`
this.closeMenus() this.closeMenus()

View File

@ -1,26 +1,24 @@
<div> <div>
<form class="flex flex-col gap-1" wire:submit.prevent='submit'> <form class="flex flex-col gap-1" wire:submit.prevent='submit'>
<div class="flex items-center gap-2"> <h1>New Server</h1>
<h1>New Server</h1>
<x-inputs.button type="submit">
Save
</x-inputs.button>
</div>
<x-inputs.input id="name" label="Name" required /> <x-inputs.input id="name" label="Name" required />
<x-inputs.input id="description" label="Description" /> <x-inputs.input id="description" label="Description" />
<x-inputs.input id="ip" label="IP Address" required /> <x-inputs.input id="ip" label="IP Address" required />
<x-inputs.input id="user" label="User" /> <x-inputs.input id="user" label="User" />
<x-inputs.input type="number" id="port" label="Port" /> <x-inputs.input type="number" id="port" label="Port" />
<x-inputs.input id="private_key_id" label="Private Key Id" readonly hidden /> <label>Private Key</label>
<select wire:model.defer="private_key_id">
<h1>Select a private key</h1> <option disabled>Select a private key</option>
<div class="flex">
@foreach ($private_keys as $key) @foreach ($private_keys as $key)
<div class="w-32 box" wire:click.defer.prevent="setPrivateKey('{{ $key->id }}')"> @if ($loop->first)
{{ $key->name }} <option selected value="{{ $key->id }}">{{ $key->name }}</option>
</div> @else
<option value="{{ $key->id }}">{{ $key->name }}</option>
@endif
@endforeach @endforeach
</div> </select>
<x-inputs.button isBold type="submit">
Save
</x-inputs.button>
</form> </form>
</div> </div>

View File

@ -47,6 +47,13 @@
'destinations' => $destinations->toArray(), 'destinations' => $destinations->toArray(),
]); ]);
} }
// Get private Keys
if (request()->query('privateKeys') === 'true') {
$privateKeys = PrivateKey::where('team_id', session('currentTeam')->id)->get();
return response()->json([
'privateKeys' => $privateKeys->toArray(),
]);
}
// Get projects // Get projects
if ((request()->query('server') && request()->query('destination') && request()->query('projects') === 'true') || request()->query('projects') === 'true') { if ((request()->query('server') && request()->query('destination') && request()->query('projects') === 'true') || request()->query('projects') === 'true') {
$projects = Project::where('team_id', session('currentTeam')->id)->get(); $projects = Project::where('team_id', session('currentTeam')->id)->get();