This commit is contained in:
Andras Bacsai 2023-06-12 22:02:10 +02:00
parent 6626795a99
commit bc79e142e5
8 changed files with 157 additions and 91 deletions

View File

@ -68,4 +68,13 @@ public function invitations()
{
return $this->hasMany(TeamInvitation::class);
}
public function sources()
{
$sources = collect([]);
$github_apps = $this->hasMany(GithubApp::class)->whereisPublic(false)->get();
$gitlab_apps = $this->hasMany(GitlabApp::class)->whereisPublic(false)->get();
// $bitbucket_apps = $this->hasMany(BitbucketApp::class)->get();
$sources = $sources->merge($github_apps)->merge($gitlab_apps);
return $sources;
}
}

View File

@ -238,7 +238,6 @@ const possibleSequences = {
},
}
const magicActions = [{
id: 0,
name: 'Deploy: Public Repository',
tags: 'git,github,public',
icon: 'git',
@ -246,7 +245,6 @@ const magicActions = [{
sequence: ['main', 'server', 'destination', 'project', 'environment', 'redirect']
},
{
id: 1,
name: 'Deploy: Private Repository (with GitHub Apps)',
tags: 'git,github,private',
icon: 'git',
@ -254,7 +252,6 @@ const magicActions = [{
sequence: ['main', 'server', 'destination', 'project', 'environment', 'redirect']
},
{
id: 2,
name: 'Deploy: Private Repository (with Deploy Key)',
tags: 'git,github,private,deploy,key',
icon: 'git',
@ -262,15 +259,6 @@ const magicActions = [{
sequence: ['main', 'server', 'destination', 'project', 'environment', 'redirect']
},
{
id: 3,
name: 'Create: Private Key',
tags: 'private,key,ssh,new,create',
icon: 'key',
new: true,
sequence: ['main', 'redirect']
},
{
id: 4,
name: 'Create: Server',
tags: 'server,ssh,new,create',
icon: 'server',
@ -278,7 +266,20 @@ const magicActions = [{
sequence: ['main', 'redirect']
},
{
id: 5,
name: 'Create: Source',
tags: 'source,git,gitlab,github,bitbucket,gitea,new,create',
icon: 'git',
new: true,
sequence: ['main', 'redirect']
},
{
name: 'Create: Private Key',
tags: 'private,key,ssh,new,create',
icon: 'key',
new: true,
sequence: ['main', 'redirect']
},
{
name: 'Create: Destination',
tags: 'destination,docker,network,new,create',
icon: 'destination',
@ -286,55 +287,46 @@ const magicActions = [{
sequence: ['main', 'server', 'redirect']
},
{
id: 6,
name: 'Goto: Dashboard',
icon: 'goto',
sequence: ['main', 'redirect']
},
{
id: 7,
name: 'Goto: Servers',
icon: 'goto',
sequence: ['main', 'redirect']
},
{
id: 8,
name: 'Goto: Projects',
icon: 'goto',
sequence: ['main', 'redirect']
},
{
id: 9,
name: 'Goto: Settings',
icon: 'goto',
sequence: ['main', 'redirect']
},
{
id: 10,
name: 'Goto: Command Center',
icon: 'goto',
sequence: ['main', 'redirect']
},
{
id: 11,
name: 'Goto: Notifications',
icon: 'goto',
sequence: ['main', 'redirect']
},
{
id: 12,
name: 'Goto: Profile',
icon: 'goto',
sequence: ['main', 'redirect']
},
{
id: 13,
name: 'Goto: Teams',
icon: 'goto',
sequence: ['main', 'redirect']
},
{
id: 14,
name: 'Goto: Switch Teams',
icon: 'goto',
sequence: ['main', 'redirect']
@ -427,12 +419,14 @@ async function goThroughSequence(actionId) {
nextSequence = sequence[sequenceState.value.currentActionIndex + 1]
sequenceState.value.sequence = sequence
sequenceState.value.selected = {
main: id
// main: id
main: actionId + 1
}
} else {
currentSequence = sequenceState.value.sequence[sequenceState.value.currentActionIndex]
nextSequence = sequenceState.value.sequence[sequenceState.value.currentActionIndex + 1]
let selectedId = sequenceState.value.magicActions[actionId].id
// let selectedId = sequenceState.value.magicActions[actionId].id
let selectedId = actionId + 1
if (uuidSelector.includes(currentSequence)) {
selectedId = sequenceState.value.magicActions[actionId].uuid
}
@ -490,59 +484,61 @@ async function redirect() {
const selected = sequenceState.value.selected
const { main, destination = null, project = null, environment = null, server = null } = selected
switch (main) {
case 0:
case 1:
targetUrl.pathname = `/project/${project}/${environment}/new`
targetUrl.searchParams.append('type', 'public')
targetUrl.searchParams.append('destination', destination)
break;
case 1:
case 2:
targetUrl.pathname = `/project/${project}/${environment}/new`
targetUrl.searchParams.append('type', 'private-gh-app')
targetUrl.searchParams.append('destination', destination)
break;
case 2:
case 3:
targetUrl.pathname = `/project/${project}/${environment}/new`
targetUrl.searchParams.append('type', 'private-deploy-key')
targetUrl.searchParams.append('destination', destination)
break;
case 3:
targetUrl.pathname = `/private-key/new`
break;
case 4:
targetUrl.pathname = `/server/new`
break;
case 5:
targetUrl.pathname = `/source/new`
break;
case 6:
targetUrl.pathname = `/private-key/new`
break;
case 7:
targetUrl.pathname = `/destination/new`
targetUrl.searchParams.append('server', server)
break;
case 6:
case 8:
targetUrl.pathname = `/`
break;
case 7:
case 9:
targetUrl.pathname = `/servers`
break;
case 8:
case 10:
targetUrl.pathname = `/projects`
break;
case 9:
case 11:
targetUrl.pathname = `/settings`
break;
case 10:
case 12:
targetUrl.pathname = `/command-center`
break;
case 11:
case 13:
targetUrl.pathname = `/profile/team/notifications`
break;
case 12:
case 14:
targetUrl.pathname = `/profile`
break;
case 13:
case 15:
targetUrl.pathname = `/profile/team`
break;
case 14:
case 16:
targetUrl.pathname = `/profile/team`
break;
}
window.location.href = targetUrl;
}

View File

@ -3,21 +3,21 @@
])
@if ($git === 'App\Models\GithubApp')
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
fill="none" stroke-linecap="round" stroke-linejoin="round">
<svg xmlns="http://www.w3.org/2000/svg" {{ $attributes->merge(['class' => 'w-6 h-6']) }} viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path
d="M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5" />
</svg>
@elseif($git === 'App\Models\GitlabApp')
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
fill="none" stroke-linecap="round" stroke-linejoin="round">
<svg xmlns="http://www.w3.org/2000/svg" {{ $attributes->merge(['class' => 'w-6 h-6']) }} viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M21 14l-9 7l-9 -7l3 -11l3 7h6l3 -7z" />
</svg>
@else
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
fill="none" stroke-linecap="round" stroke-linejoin="round">
<svg xmlns="http://www.w3.org/2000/svg" {{ $attributes->merge(['class' => 'w-6 h-6']) }} viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M16 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
<path d="M12 8m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />

View File

@ -3,7 +3,7 @@
<form wire:submit.prevent='submit'>
<div class="flex items-center gap-2">
<h1>GitHub App</h1>
<div class="flex gap-2 ">
<div class="flex gap-2">
@if ($github_app->app_id)
<x-forms.button type="submit">Save</x-forms.button>
<x-forms.button x-on:click.prevent="deleteSource = true">
@ -29,9 +29,10 @@
@endif
</div>
</div>
<div class="pt-2 pb-10 text-sm">Your Private GitHub App for private repositories.</div>
@if (!$github_app->app_id)
<div class="pb-4">
<div class="text-sm">You need to register a GitHub App before using this source!</div>
<div class="flex items-center gap-4 pt-2 pb-10">
<div class="text-sm">You need to register a GitHub App before using this source:</div>
<form>
<x-forms.button x-on:click.prevent="createGithubApp">Register a GitHub
Application
@ -39,36 +40,46 @@
</form>
</div>
@endif
<x-forms.input id="github_app.name" label="App Name" required />
<div class="flex gap-2">
<x-forms.input id="github_app.name" label="App Name" required />
@if ($github_app->app_id)
<x-forms.input id="github_app.organization" label="Organization" disabled
placeholder="Personal user if empty" />
@else
<x-forms.input id="github_app.organization" label="Organization" placeholder="Personal user if empty" />
@endif
</div>
<div class="flex gap-2">
<x-forms.input id="github_app.html_url" label="HTML Url" disabled />
<x-forms.input id="github_app.api_url" label="API Url" disabled />
</div>
<div class="flex gap-2">
@if ($github_app->html_url === 'https://github.com')
<x-forms.input id="github_app.custom_user" label="User" disabled />
<x-forms.input type="number" id="github_app.custom_port" label="Port" disabled />
@else
<x-forms.input id="github_app.custom_user" label="User" required />
<x-forms.input type="number" id="github_app.custom_port" label="Port" required />
@endif
</div>
@if ($github_app->app_id)
<x-forms.input id="github_app.organization" label="Organization" disabled
placeholder="Personal user if empty" />
@else
<x-forms.input id="github_app.organization" label="Organization" placeholder="Personal user if empty" />
@endif
<x-forms.input id="github_app.html_url" label="HTML Url" disabled />
<x-forms.input id="github_app.api_url" label="API Url" disabled />
@if ($github_app->html_url === 'https://github.com')
<x-forms.input id="github_app.custom_user" label="User" disabled />
<x-forms.input type="number" id="github_app.custom_port" label="Port" disabled />
@else
<x-forms.input id="github_app.custom_user" label="User" required />
<x-forms.input type="number" id="github_app.custom_port" label="Port" required />
@endif
@if ($github_app->app_id)
<x-forms.input type="number" id="github_app.app_id" label="App Id" disabled />
<x-forms.input type="number" id="github_app.installation_id" label="Installation Id" disabled />
<x-forms.input id="github_app.client_id" label="Client Id" type="password" disabled />
<x-forms.input id="github_app.client_secret" label="Client Secret" type="password" disabled />
<x-forms.input id="github_app.webhook_secret" label="Webhook Secret" type="password" disabled />
<x-forms.checkbox noDirty label="System Wide?" instantSave id="is_system_wide" />
@else
<x-forms.checkbox noDirty label="System Wide?" instantSave id="is_system_wide" />
<div class="py-2">
<div class="flex gap-2">
<x-forms.input type="number" id="github_app.app_id" label="App Id" disabled />
<x-forms.input type="number" id="github_app.installation_id" label="Installation Id" disabled />
</div>
<div class="flex gap-2">
<x-forms.input id="github_app.client_id" label="Client Id" type="password" disabled />
<x-forms.input id="github_app.client_secret" label="Client Secret" type="password" disabled />
<x-forms.input id="github_app.webhook_secret" label="Webhook Secret" type="password" disabled />
</div>
<x-forms.checkbox noDirty label="System Wide?"
helper="If checked, this GitHub App will be available for everyone in this Coolify instance."
instantSave id="is_system_wide" />
@else
<x-forms.checkbox
helper="If checked, this GitHub App will be available for everyone in this Coolify instance." noDirty
label="System Wide?" instantSave id="is_system_wide" />
@endif
</form>
@if (!$github_app->app_id)

View File

@ -1,18 +1,22 @@
<div>
<form wire:submit.prevent='createGitHubApp'>
<div class="flex items-start gap-2 pt-6">
<h2 class="">General</h2>
<x-forms.button type="submit">
Save
</x-forms.button>
<form wire:submit.prevent='createGitHubApp' class="flex flex-col">
<h2>GitHub App</h2>
<div class="flex gap-2">
<x-forms.input id="name" label="Name" required />
<x-forms.input helper="If empty, your GitHub user will be used." id="organization" label="Organization" />
</div>
<h3 class="py-4">Advanced</h3>
<div class="flex gap-2">
<x-forms.input id="html_url" label="HTML Url" required />
<x-forms.input id="api_url" label="API Url" required />
</div>
<div class="flex gap-2">
<x-forms.input id="custom_user" label="Custom Git User" required />
<x-forms.input id="custom_port" label="Custom Git Port" required />
</div>
<x-forms.input id="name" label="Name" required />
<x-forms.input helper="If empty, your GitHub user will be used." id="organization" label="Organization" />
<h3 class="pt-4">Advanced</h3>
<x-forms.input id="html_url" label="HTML Url" required />
<x-forms.input id="api_url" label="API Url" required />
<x-forms.input id="custom_user" label="Custom Git User" required />
<x-forms.input id="custom_port" label="Custom Git Port" required />
<x-forms.checkbox class="pt-2" id="is_system_wide" label="System Wide" />
<x-forms.button isHighlighted type="submit">
Create New Source
</x-forms.button>
</form>
</div>

View File

@ -0,0 +1,31 @@
<x-layout>
<h1>Sources</h1>
<div class="pt-2 pb-10 text-sm">All Sources</div>
<div class="grid grid-cols-2 gap-2">
@forelse ($sources as $source)
@if ($source->getMorphClass() === 'App\Models\GithubApp')
<a class="flex gap-4 text-center hover:no-underline box group"
href="{{ route('source.github.show', ['github_app_uuid' => data_get($source, 'uuid')]) }}">
<x-git-icon class="text-white w-9 h-9" git="{{ $source->getMorphClass() }}" />
<div class="group-hover:text-white">
<div>{{ $source->name }}</div>
</div>
</a>
@endif
@if ($source->getMorphClass() === 'App\Models\GitlabApp')
<a class="flex gap-4 text-center hover:no-underline box group"
href="{{ route('source.gitlab.show', ['gitlab_app_uuid' => data_get($source, 'uuid')]) }}">
<x-git-icon class="text-white w-9 h-9" git="{{ $source->getMorphClass() }}" />
<div class="group-hover:text-white">
<div>{{ $source->name }}</div>
</div>
</a>
@endif
@empty
<div>
<div>No sources found.</div>
<x-use-magic-bar />
</div>
@endforelse
</div>
</x-layout>

View File

@ -1,7 +1,8 @@
<x-layout>
<h1>New Source</h1>
<div class="pt-2 pb-10 text-sm">Add source providers for your applications.</div>
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : '' }">
<div class="flex justify-center h-full gap-2">
<div class="flex justify-center h-full gap-2 pb-6">
<a class="flex items-center justify-center w-1/2 p-2 text-sm transition-colors rounded-none min-h-12 bg-coolgray-200 hover:bg-coollabs-100 hover:text-white hover:no-underline"
:class="activeTab === 'github' && 'bg-coollabs text-white'"
@click.prevent="activeTab = 'github'; window.location.hash = 'github'" href="#">GitHub
@ -15,7 +16,7 @@
<livewire:source.github.create />
</div>
<div x-cloak x-show="activeTab === 'gitlab'" class="h-full">
GitLab here
WIP
</div>
</div>
</x-layout>

View File

@ -10,6 +10,7 @@
use App\Models\StandaloneDocker;
use App\Models\SwarmDocker;
use App\Models\GithubApp;
use App\Models\GitlabApp;
use App\Models\Server;
use App\Models\User;
use App\Notifications\TransactionalEmails\ResetPasswordEmail;
@ -92,6 +93,12 @@
Route::middleware(['auth'])->group(function () {
Route::get('/source/new', fn () => view('source.new'))->name('source.new');
Route::get('/sources', function () {
$sources = session('currentTeam')->sources();
return view('source.all', [
'sources' => $sources,
]);
})->name('source.all');
Route::get('/source/github/{github_app_uuid}', function (Request $request) {
$github_app = GithubApp::where('uuid', request()->github_app_uuid)->first();
$name = Str::of(Str::kebab($github_app->name))->start('coolify-');
@ -109,6 +116,13 @@
'installation_url' => $installation_url,
]);
})->name('source.github.show');
Route::get('/source/gitlab/{gitlab_app_uuid}', function (Request $request) {
$gitlab_app = GitlabApp::where('uuid', request()->gitlab_app_uuid)->first();
return view('source.gitlab.show', [
'gitlab_app' => $gitlab_app,
]);
})->name('source.gitlab.show');
});
Route::middleware(['auth'])->group(function () {