more items in magic bar

This commit is contained in:
Andras Bacsai 2023-05-12 11:59:02 +02:00
parent 19e1f60d69
commit a1483a4111
5 changed files with 114 additions and 27 deletions

View File

@ -58,11 +58,22 @@ static public function validated()
{
return Server::where('team_id', session('currentTeam')->id)->whereRelation('settings', 'is_validated', true)->get();
}
static public function destinations($server_uuid)
static public function destinations(string|null $server_uuid)
{
if ($server_uuid) {
$server = Server::where('team_id', session('currentTeam')->id)->where('uuid', $server_uuid)->firstOrFail();
$standaloneDocker = collect($server->standaloneDockers->all());
$swarmDocker = collect($server->swarmDockers->all());
return $standaloneDocker->concat($swarmDocker);
} else {
$servers = Server::where('team_id', session('currentTeam')->id)->get();
$standaloneDocker = $servers->map(function ($server) {
return $server->standaloneDockers;
})->flatten();
$swarmDocker = $servers->map(function ($server) {
return $server->swarmDockers;
})->flatten();
return $standaloneDocker->concat($swarmDocker);
}
}
}

View File

@ -4,8 +4,9 @@
<div>
<div class="mainMenu">
<input x-ref="search" x-model="search" class="w-96" x-on:click="checkMainMenu"
x-on:click.outside="closeMenus" placeholder="Search or jump to..." x-on:keyup.escape="clearSearch"
x-on:keyup.down="focusNext(items.length)" x-on:keyup.up="focusPrev(items.length)"
x-on:click.outside="closeMenus" placeholder="Search, jump or create... magically..."
x-on:keyup.escape="clearSearch" x-on:keyup.down="focusNext(items.length)"
x-on:keyup.up="focusPrev(items.length)"
x-on:keyup.enter="focusedIndex !== '' && await set(filteredItems()[focusedIndex]?.next ?? 'server',filteredItems()[focusedIndex]?.name)" />
</div>
<div x-cloak x-show="mainMenu" class="absolute text-sm top-11 w-[25rem] bg-neutral-800">
@ -19,6 +20,8 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
x-text="item.type"></span>
<span class="px-2 mr-1 text-xs bg-purple-600 rounded" x-show="item.type === 'Jump'"
x-text="item.type"></span>
<span class="px-2 mr-1 text-xs bg-blue-600 rounded" x-show="item.type === 'New'"
x-text="item.type"></span>
<span x-text="item.name"></span>
</div>
</template>
@ -125,6 +128,24 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
</div>
</div>
</template>
{{-- Destinations --}}
<template x-cloak x-if="destinationsMenu">
<div x-on:click.outside="closeMenus">
<input x-ref="search" x-model="search" class="w-96" placeholder="Select a destination..."
x-on:keyup.down="focusNext(Destinations.length)" x-on:keyup.up="focusPrev(Destinations.length)"
x-on:keyup.enter="focusedIndex !== '' && await set('jumpToDestination',filteredDestinations()[focusedIndex].uuid)" />
<div class="absolute text-sm top-11 w-[25rem] bg-neutral-800">
<template x-for="(destination,index) in filteredDestinations" :key="destination.name ?? destination">
<div x-on:click="await set('jumpToDestination',destination.uuid)"
:class="focusedIndex === index && 'bg-neutral-700'"
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="destination.name"></span>
</div>
</template>
</div>
</div>
</template>
</div>
<script>
@ -135,7 +156,8 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
!this.destinationMenu &&
!this.projectMenu &&
!this.environmentMenu &&
!this.projectsMenu
!this.projectsMenu &&
!this.destinationsMenu
},
focus() {
if (this.$refs.search) this.$refs.search.focus()
@ -163,6 +185,7 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
mainMenu: false,
serverMenu: false,
destinationMenu: false,
destinationsMenu: false,
projectMenu: false,
projectsMenu: false,
environmentMenu: false,
@ -199,17 +222,48 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
name: 'Database',
type: 'Add',
tags: 'data,database,mysql,postgres,sql,sqlite,redis,mongodb,maria,percona',
disabled: true,
},
{
name: 'Server',
type: 'New',
tags: 'new,server',
next: 'newServer'
},
{
name: 'Destination',
type: 'New',
tags: 'new,destination',
next: 'newDestination'
},
{
name: 'Private Key',
type: 'New',
tags: 'new,private-key,ssh,key',
next: 'newPrivateKey'
},
{
name: 'Source',
type: 'New',
tags: 'new,source,github,gitlab,bitbucket',
next: 'newSource'
},
{
name: 'Servers',
type: 'Jump',
tags: 'servers',
next: 'server'
},
{
name: 'Projects',
type: 'Jump',
tags: 'projects',
next: 'projects'
},
{
name: 'Destinations',
type: 'Jump',
tags: 'destinations',
next: 'destinations'
}
],
focusPrev(maxLength) {
@ -257,7 +311,8 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
filteredItems() {
if (this.search === '') return this.items
return this.items.filter(item => {
return item.name.toLowerCase().includes(this.search.toLowerCase())
return item.name.toLowerCase().includes(this.search.toLowerCase()) ||
item.tags.toLowerCase().includes(this.search.toLowerCase())
})
},
filteredServers() {
@ -365,7 +420,6 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
this.projectMenu = true
break
case 'projects':
response = await fetch('/magic?projects=true');
if (response.ok) {
const {
@ -376,6 +430,17 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
this.closeMenus()
this.projectsMenu = true
break
case 'destinations':
response = await fetch('/magic?destinations=true');
if (response.ok) {
const {
destinations
} = await response.json();
this.destinations = destinations;
}
this.closeMenus()
this.destinationsMenu = true
break
case 'environment':
if (this.focusedIndex === 0) {
this.focusedIndex = ''
@ -421,7 +486,27 @@ class="py-2 pl-4 cursor-pointer hover:bg-neutral-700">
this.closeMenus()
break
case 'jumpToProject':
window.location = `/project/${id}/`
window.location = `/project/${id}`
this.closeMenus()
break
case 'jumpToDestination':
window.location = `/destination/${id}`
this.closeMenus()
break
case 'newServer':
window.location = `/server/new`
this.closeMenus()
break
case 'newDestination':
window.location = `/destination/new`
this.closeMenus()
break
case 'newPrivateKey':
window.location = `/private-key/new`
this.closeMenus()
break
case 'newSource':
window.location = `/source/new`
this.closeMenus()
break
}

View File

@ -5,33 +5,25 @@
@empty
<p>No projects found.</p>
@endforelse
<h1>Servers <a href="{{ route('server.new') }}">
<x-inputs.button>New</x-inputs.button>
</a></h1>
<h1>Servers </h1>
@forelse ($servers as $server)
<a href="{{ route('server.show', [$server->uuid]) }}">{{ data_get($server, 'name') }}</a>
@empty
<p>No servers found.</p>
@endforelse
<h1>Destinations <a href="{{ route('destination.new') }}">
<x-inputs.button>New</x-inputs.button>
</a></h1>
<h1>Destinations </h1>
@forelse ($destinations as $destination)
<a href="{{ route('destination.show', [$destination->uuid]) }}">{{ data_get($destination, 'name') }}</a>
@empty
<p>No destinations found.</p>
@endforelse
<h1>Private Keys <a href="{{ route('private-key.new') }}">
<x-inputs.button>New</x-inputs.button>
</a></h1>
<h1>Private Keys </h1>
@forelse ($private_keys as $private_key)
<a href="{{ route('private-key.show', [$private_key->uuid]) }}">{{ data_get($private_key, 'name') }}</a>
@empty
<p>No servers found.</p>
@endforelse
<h1>GitHub Apps <a href="{{ route('source.new') }}">
<x-inputs.button>New</x-inputs.button>
</a></h1>
<h1>GitHub Apps </h1>
@forelse ($github_apps as $github_app)
<a href="{{ route('source.github.show', [$github_app->uuid]) }}">{{ data_get($github_app, 'name') }}</a>
@empty

View File

@ -1,6 +1,6 @@
<div>
<form class="flex items-end justify-center gap-2" wire:submit.prevent='runCommand'>
<x-inputs.input noDirty noLabel autofocus id="command" label="Command" required />
<x-inputs.input noDirty noLabel id="command" label="Command" required />
<select wire:model.defer="server">
@foreach ($servers as $server)
<option value="{{ $server->uuid }}">{{ $server->name }}</option>

View File

@ -41,7 +41,7 @@
}
// Get destinations
if (request()->query('server') && request()->query('destinations') === 'true') {
if ((request()->query('server') && request()->query('destinations') === 'true') || request()->query('destinations') === 'true') {
$destinations = Server::destinations(request()->query('server'));
return response()->json([
'destinations' => $destinations->toArray(),
@ -200,7 +200,6 @@
});
Route::middleware(['auth'])->group(function () {
Route::get('/project/new', fn () => view('project.new', ['type' => 'project']))->name('project.new');
Route::get(
'/project/{project_uuid}',
[ProjectController::class, 'environments']