This commit is contained in:
Andras Bacsai
2023-05-17 15:46:20 +02:00
parent c350018716
commit f2e91f97ed
14 changed files with 430 additions and 251 deletions

View File

@@ -3,37 +3,43 @@
@tailwind utilities;
body {
@apply bg-coolgray-100 text-white font-sans;
@apply bg-coolgray-100 text-white;
}
input {
@apply input w-full max-w-xl input-bordered input-sm;
}
textarea {
@apply textarea textarea-sm;
}
label {
@apply text-sm pb-2 tracking-wider;
}
input,
/* input,
textarea {
@apply border border-solid border-coolgray-500 bg-coolgray-200 rounded p-2 px-4 text-white outline-none transition-all;
}
input,
textarea {
@apply disabled:text-neutral-600 read-only:text-neutral-600 read-only:select-none read-only:bg-coolgray-200/50;
}
} */
select {
@apply border border-solid border-coolgray-400 rounded p-2 px-4 bg-coolgray-200 text-white disabled:text-neutral-600 read-only:select-none outline-none;
}
button {
@apply border border-solid border-coolgray-200 px-3 p-1 cursor-pointer;
@apply btn btn-xs btn-ghost no-animation normal-case;
}
button[type="submit"] {
@apply btn-primary btn-sm;
}
h1 {
@apply text-3xl font-bold pb-4;
}
h2 {
@apply text-xl font-bold pb-4;
@apply text-2xl font-bold pb-4;
}
h3 {
@apply text-lg font-bold pb-4;
@apply text-xl font-bold pb-4;
}
a {
@apply text-neutral-400 m-2 hover:underline;
a{
@apply hover:text-white text-sm;
}
.box {
@@ -45,16 +51,16 @@ a {
}
.main-menu:after {
content: "/";
@apply absolute right-0 top-0 text-neutral-400 px-2 pt-[0.5rem];
@apply font-bold absolute right-0 top-0 text-neutral-400 px-2 pt-[0.7rem];
}
.magic-input {
@apply w-[25rem] rounded outline-none bg-coolgray-400 focus:bg-neutral-700 text-white;
@apply input input-ghost w-96 placeholder:text-neutral-400 text-sm;
}
.magic-items {
@apply absolute top-12 w-[25rem] bg-coolgray-200 border-b-2 border-r-2 border-l-2 border-solid border-coolgray-100 rounded-b;
@apply absolute top-16 mt-2 w-[24rem] bg-coolgray-200 rounded-xl outline outline-coolgray-500;
}
.magic-item {
@apply m-2 py-2 pl-4 cursor-pointer hover:bg-neutral-700 text-neutral-300 hover:text-white;
@apply text-sm flex items-center gap-4 m-2 py-2 pl-4 cursor-pointer hover:bg-coolgray-500 text-neutral-400 hover:text-white rounded-xl transition-colors hover:shadow;
}
.magic-item-focused {
@apply bg-neutral-700 text-white;

View File

@@ -1,29 +1,12 @@
@props([
'isWarning' => null,
'isBold' => false,
'disabled' => null,
'defaultClass' => 'text-white hover:bg-coollabs h-10 rounded transition-colors',
'defaultWarningClass' => 'text-red-500 hover:text-white hover:bg-red-600 h-10 rounded',
'disabledClass' => 'text-neutral-400 h-10 rounded',
'loadingClass' => 'text-black bg-green-500 h-10 rounded',
'confirm' => null,
'confirmAction' => null,
])
<button {{ $attributes }} @class([
$defaultClass => !$confirm && !$isWarning && !$disabled && !$isBold,
$defaultWarningClass => ($confirm || $isWarning) && !$disabled,
$disabledClass => $disabled,
$isBold => $isBold
? 'bg-coollabs text-white hover:bg-coollabs-100 h-10 rounded transition-colors'
: '',
]) @if ($attributes->whereStartsWith('wire:click') && !$disabled)
wire:target="{{ explode('(', $attributes->whereStartsWith('wire:click')->first())[0] }}"
wire:loading.delay.class="{{ $loadingClass }}" wire:loading.delay.attr="disabled"
wire:loading.delay.class.remove="{{ $defaultClass }} {{ $attributes->whereStartsWith('class')->first() }}"
@endif
@if ($disabled !== null)
disabled title="{{ $disabled }}"
@endif
<button {{ $attributes }}
@if ($attributes->whereStartsWith('wire:click') && !$disabled) wire:target="{{ explode('(', $attributes->whereStartsWith('wire:click')->first())[0] }}"
wire:loading.delay.class='loading' wire:loading.delay.attr="disabled" @endif
@if ($disabled !== null) disabled title="{{ $disabled }}" @endif
@isset($confirm)
x-on:click="toggleConfirmModal('{{ $confirm }}', '{{ explode('(', $confirmAction)[0] }}')"
@endisset

View File

@@ -0,0 +1,24 @@
@props([
'id' => $attributes->has('id') || $attributes->has('label'),
'required' => $attributes->has('required'),
'label' => $attributes->has('label'),
'helper' => $attributes->has('helper'),
'instantSave' => $attributes->has('instantSave'),
'noLabel' => $attributes->has('noLabel'),
'noDirty' => $attributes->has('noDirty'),
'disabled' => null,
])
<label {{ $attributes->merge(['class' => 'flex items-center gap-16 cursor-pointer']) }}>
<span class="label-text">
@if ($label)
{{ $label }}
@else
{{ $id }}
@endif
</span>
<input type="checkbox" @if ($disabled !== null) disabled @endif class="toggle" name={{ $id }}
@if (!$noDirty) wire:dirty.class="input-warning" @endif
@if ($instantSave) wire:click='instantSave' wire:model.defer={{ $id }} @else wire:model.defer={{ $value ?? $id }} @endif />
</label>
</div>

View File

@@ -1,43 +1,51 @@
@props([
'id' => $attributes->has('id') || $attributes->has('label'),
'type' => 'text',
'required' => $attributes->has('required'),
'label' => $attributes->has('label'),
'helper' => $attributes->has('helper'),
'instantSave' => $attributes->has('instantSave'),
'noLabel' => $attributes->has('noLabel'),
'noDirty' => $attributes->has('noDirty'),
'hidden' => $attributes->has('hidden'),
])
<span @class([
'flex' => $type === 'checkbox',
'flex flex-col' => $type !== 'checkbox',
])>
<div class="w-full max-w-xs form-control">
@if (!$noLabel)
<label for={{ $id }} @if (!$noDirty) wire:dirty.class="text-amber-300" @endif
@if ($hidden) class="hidden" @endif wire:target={{ $id }}>
@if ($label)
{{ $label }}
@else
{{ $id }}
@endif
@if ($required)
*
@endif
<label class="label">
<span class="label-text">
@if ($label)
{{ $label }}
@else
{{ $id }}
@endif
@if ($required)
<span class="text-warning">*</span>
@endif
@if ($helper)
<div class="dropdown dropdown-right">
<label tabindex="0" class="btn btn-circle btn-ghost btn-xs text-warning">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
class="z-0 w-4 h-4 stroke-current">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</label>
<div tabindex="0"
class="w-64 border-2 shadow border-coolgray-500 card compact dropdown-content bg-coolgray-200">
<div class="card-body">
{{ $helper }}
</div>
</div>
</div>
@endif
</span>
</label>
@endif
@if ($type === 'textarea')
<textarea @if (!$noDirty) wire:dirty.class="text-black bg-amber-300" @endif {{ $attributes }}
required={{ $required }} type={{ $type }} id={{ $id }} wire:model.defer={{ $id }}></textarea>
@else
<input {{ $attributes }} @if ($required) required @endif
@if (!$noDirty) wire:dirty.class="text-black bg-amber-300" @endif
type={{ $type }} id={{ $id }} name={{ $id }}
@if ($instantSave) wire:click='instantSave' wire:model.defer={{ $id }} @else wire:model.defer={{ $value ?? $id }} @endif
@if ($hidden) class="hidden" @endif />
@endif
<input {{ $attributes }} name={{ $id }}
@if ($instantSave) wire:click='instantSave' wire:model.defer={{ $id }} @else wire:model.defer={{ $value ?? $id }} @endif
@if (!$noDirty) wire:dirty.class="input-warning" @endif />
@error($id)
<div class="text-red-500">{{ $message }}</div>
<label class="label">
<span class="text-red-500 label-text-alt">{{ $message }}</span>
</label>
@enderror
</span>
</div>

View File

@@ -0,0 +1,51 @@
@props([
'id' => $attributes->has('id') || $attributes->has('label'),
'required' => $attributes->has('required'),
'label' => $attributes->has('label'),
'helper' => $attributes->has('helper'),
'instantSave' => $attributes->has('instantSave'),
'noLabel' => $attributes->has('noLabel'),
'noDirty' => $attributes->has('noDirty'),
])
<div class="w-full max-w-xs form-control">
@if (!$noLabel)
<label class="label">
<span class="label-text">
@if ($label)
{{ $label }}
@else
{{ $id }}
@endif
@if ($required)
<span class="text-warning">*</span>
@endif
@if ($helper)
<div class="dropdown dropdown-right">
<label tabindex="0" class="btn btn-circle btn-ghost btn-xs text-warning">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
class="w-4 h-4 stroke-current">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</label>
<div tabindex="0"
class="w-64 border-2 shadow border-coolgray-500 card compact dropdown-content bg-coolgray-200 ">
<div class="card-body">
{{ $helper }}
</div>
</div>
</div>
@endif
</span>
</label>
@endif
<textarea {{ $attributes }} name={{ $id }}
@if ($instantSave) wire:click='instantSave' wire:model.defer={{ $id }} @else wire:model.defer={{ $value ?? $id }} @endif
@if (!$noDirty) wire:dirty.class="input-warning" @endif></textarea>
@error($id)
<label class="label">
<span class="text-red-500 label-text-alt">{{ $message }}</span>
</label>
@enderror
</div>

View File

@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<html data-theme="coollabs" lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="h-full bg-coolgray-100">
<head>
<meta charset="utf-8">

View File

@@ -1,4 +1,4 @@
<div x-data="magicsearchbar" @slash.window="mainMenu = true" class="fixed -translate-x-1/2 left-1/2">
<div x-data="magicsearchbar" @slash.window="mainMenu = true">
{{-- Main --}}
<template x-cloak x-if="isMainMenu">
<div>
@@ -13,13 +13,13 @@
<template x-for="(item,index) in filteredItems" :key="item.name">
<div x-on:click="await set(item.next ?? 'server',item.name)"
:class="focusedIndex === index && 'magic-item-focused'" class="magic-item">
<span class="px-2 mr-1 text-xs text-white bg-green-600 rounded" x-show="item.type === 'App'"
<span class="w-12 w- badge badge-primary badge-sm" x-show="item.type === 'Apps'"
x-text="item.type"></span>
<span class="px-2 mr-1 text-xs text-white bg-indigo-600 rounded" x-show="item.type === 'Add'"
<span class="w-12 badge badge-secondary badge-sm" x-show="item.type === 'Add'"
x-text="item.type"></span>
<span class="px-2 mr-1 text-xs text-white bg-purple-600 rounded" x-show="item.type === 'Jump'"
<span class="w-12 badge badge-success badge-sm" x-show="item.type === 'Jump'"
x-text="item.type"></span>
<span class="px-2 mr-1 text-xs text-white bg-blue-600 rounded" x-show="item.type === 'New'"
<span class="w-12 badge badge-success badge-sm" x-show="item.type === 'New'"
x-text="item.type"></span>
<span x-text="item.name"></span>
</div>
@@ -42,7 +42,7 @@
<template x-for="(server,index) in filteredServers" :key="server.name ?? server">
<div x-on:click="await set('destination',server.uuid)"
:class="focusedIndex === index && 'magic-item-focused'" class="magic-item">
<span class="px-2 mr-1 text-xs text-white bg-purple-600 rounded">Server</span>
<span class="w-12 badge badge-primary badge-sm">Server</span>
<span x-text="server.name"></span>
</div>
</template>
@@ -65,7 +65,7 @@
<template x-for="(destination,index) in filteredDestinations" :key="destination.name ?? destination">
<div x-on:click="await set('project',destination.uuid)"
:class="focusedIndex === index && 'magic-item-focused'" class="magic-item">
<span class="px-2 mr-1 text-xs text-white bg-purple-700 rounded">Destination</span>
<span class="w-12 badge badge-primary badge-sm">Destination</span>
<span x-text="destination.name"></span>
</div>
</template>
@@ -88,7 +88,7 @@
<template x-for="(project,index) in filteredProjects" :key="project.name ?? project">
<div x-on:click="await set('environment',project.uuid)"
:class="focusedIndex === index + 1 && 'magic-item-focused'" class="magic-item">
<span class="px-2 mr-1 text-xs text-white bg-purple-700 rounded">Project</span>
<span class="w-12 badge badge-primary badge-sm">Project</span>
<span x-text="project.name"></span>
</div>
</template>
@@ -111,7 +111,7 @@
<template x-for="(environment,index) in filteredEnvironments" :key="environment.name ?? environment">
<div x-on:click="await set('jump',environment.name)"
:class="focusedIndex === index + 1 && 'magic-item-focused'" class="magic-item">
<span class="px-2 mr-1 text-xs text-white bg-purple-700 rounded">Env</span>
<span class="w-12 badge badge-primary badge-sm">Env</span>
<span x-text="environment.name"></span>
</div>
</template>
@@ -134,7 +134,7 @@
<template x-for="(project,index) in filteredProjects" :key="project.name ?? project">
<div x-on:click="await set('jumpToProject',project.uuid)"
:class="focusedIndex === index && 'magic-item-focused'" class="magic-item">
<span class="px-2 mr-1 text-xs text-white bg-purple-700 rounded">Jump</span>
<span class="w-12 badge badge-primary badge-sm">Jump</span>
<span x-text="project.name"></span>
</div>
</template>
@@ -157,7 +157,7 @@
<template x-for="(destination,index) in filteredDestinations" :key="destination.name ?? destination">
<div x-on:click="await set('jumpToDestination',destination.uuid)"
:class="focusedIndex === index && 'magic-item-focused'" class="magic-item">
<span class="px-2 mr-1 text-xs bg-purple-700 rounded">Jump</span>
<span class="w-12 badge badge-primary badge-sm">Jump</span>
<span x-text="destination.name"></span>
</div>
</template>
@@ -180,7 +180,7 @@
<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="magic-item">
<span class="px-2 mr-1 text-xs bg-purple-700 rounded">Jump</span>
<span class="w-12 badge badge-primary badge-sm">Jump</span>
<span x-text="privateKey.name"></span>
</div>
</template>
@@ -203,7 +203,7 @@
<template x-for="(source,index) in filteredSources" :key="source.name ?? source">
<div x-on:click="await set('jumpToSource',source)"
:class="focusedIndex === index && 'magic-item-focused'" class="magic-item">
<span class="px-2 mr-1 text-xs bg-purple-700 rounded">Jump</span>
<span class="w-12 badge badge-primary badge-sm">Jump</span>
<span x-text="source.name"></span>
</div>
</template>
@@ -281,18 +281,18 @@
focusedIndex: "",
items: [{
name: 'Public Repository',
type: 'App',
tags: 'application,public,repository,github,gitlab,bitbucket,git',
type: 'Apps',
tags: 'Appslication,public,repository,github,gitlab,bitbucket,git',
},
{
name: 'Private Repository (with GitHub App)',
type: 'App',
tags: 'application,private,repository,github,gitlab,bitbucket,git',
name: 'Private Repository (with GitHub Apps)',
type: 'Apps',
tags: 'Appslication,private,repository,github,gitlab,bitbucket,git',
},
{
name: 'Private Repository (with Deploy Key)',
type: 'App',
tags: 'application,private,repository,github,gitlab,bitbucket,git',
type: 'Apps',
tags: 'Appslication,private,repository,github,gitlab,bitbucket,git',
},
{
name: 'Server',
@@ -352,7 +352,7 @@
{
name: 'Sources',
type: 'Jump',
tags: 'jump,github,apps,source',
tags: 'jump,github,Appss,source',
next: 'sources'
}
],
@@ -606,7 +606,7 @@
`/project/${this.selectedProject}/${this.selectedEnvironment}/new?type=public&destination=${this.selectedDestination}`
} else if (this.selectedAction === 1) {
window.location =
`/project/${this.selectedProject}/${this.selectedEnvironment}/new?type=private-gh-app&destination=${this.selectedDestination}`
`/project/${this.selectedProject}/${this.selectedEnvironment}/new?type=private-gh-Apps&destination=${this.selectedDestination}`
} else if (this.selectedAction === 2) {
window.location =
`/project/${this.selectedProject}/${this.selectedEnvironment}/new?type=private-deploy-key&destination=${this.selectedDestination}`

View File

@@ -1,35 +1,96 @@
@auth
<nav>
<div class="flex px-2 py-1">
<div class="flex gap-2 text-sm">
<a href="/">
Home
</a>
<a href="/command-center">
Command Center
</a>
<a href="/profile">
Profile
</a>
<a href="/profile/team">
Team
</a>
@if (auth()->user()->isRoot())
<a href="/settings">
Settings
</a>
@endif
<div class="navbar">
<div class="navbar-start">
<div class="dropdown">
<label tabindex="0" class="btn btn-ghost xl:hidden">
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h8m-8 6h16" />
</svg>
</label>
<ul tabindex="0" class="p-2 mt-3 shadow menu menu-compact dropdown-content bg-base-100 rounded-box w-52">
<li>
<a href="/" class="justify-between">
Home
</a>
</li>
@if (auth()->user()->isRoot())
<li>
<a href="/settings" class="justify-between">
Settings
</a>
</li>
@endif
<li>
<a href="/profile" class="justify-between">
Profile
</a>
</li>
<li>
<a href="/profile/team" class="justify-between">
Team
</a>
</li>
<li>
<a href="/command-center" class="justify-between">
Command Center
</a>
</li>
@if (auth()->user()->isRoot())
<li>
<livewire:force-upgrade />
</li>
@endif
<li>
<form action="/logout" method="POST">
@csrf
<button type="submit">Logout</button>
</form>
</li>
</ul>
</div>
<x-magic-bar />
<div class="flex-1"></div>
<div class="flex gap-2 text-sm">
{{-- <livewire:check-update /> --}}
<livewire:force-upgrade />
<form action="/logout" method="POST">
@csrf
<button class="m-1 border-none hover:underline text-neutral-400" type="submit">Logout</button>
</form>
<a href="/" class="text-xl normal-case btn btn-ghost">Coolify</a>
<div class="form-control">
<x-magic-bar />
</div>
</div>
</nav>
<div class="hidden navbar-end xl:flex">
<ul class="px-1 menu menu-horizontal text-neutral-400">
@if (auth()->user()->isRoot())
<li>
<a href="/settings" class="justify-between link link-hover hover:bg-transparent">
Settings
</a>
</li>
@endif
<li>
<a href="/profile" class="justify-between link link-hover hover:bg-transparent">
Profile
</a>
</li>
<li>
<a href="/profile/team" class="justify-between link link-hover hover:bg-transparent">
Team
</a>
</li>
<li>
<a class="justify-between link link-hover hover:bg-transparent" href="/command-center">
Command Center
</a>
</li>
@if (auth()->user()->isRoot())
<li>
<livewire:force-upgrade />
</li>
@endif
<li>
<form action="/logout" method="POST" class="hover:bg-transparent">
@csrf
<button class="font-normal link link-hover hover:bg-transparent hover:text-white"
type="submit">Logout</button>
</form>
</li>
</ul>
</div>
</div>
@endauth

View File

@@ -1,5 +1,3 @@
<div>
@if (auth()->user()->teams->contains(0))
<button wire:click='upgrade' class="m-1 border-none hover:underline text-neutral-400">Force Upgrade</button>
@endif
</div>
<a href="#" class="justify-between font-normal link link-hover hover:bg-transparent hover:text-white"
wire:click='upgrade'>Force
Upgrade</a>

View File

@@ -1,4 +1,4 @@
<div x-data="{ deleteApplication: false }">
<div x-data="{ deleteApplication: false }" class="flex items-center gap-2">
<x-naked-modal show="deleteApplication" />
@if ($application->status === 'running')
<x-inputs.button wire:click='start'>Rebuild</x-inputs.button>
@@ -8,7 +8,7 @@
<x-inputs.button wire:click='start'>Start</x-inputs.button>
<x-inputs.button wire:click='forceRebuild'>Start (no cache)</x-inputs.button>
@endif
<x-inputs.button isWarning x-on:click.prevent="deleteApplication = true">
<x-inputs.button x-on:click.prevent="deleteApplication = true">
Delete</x-inputs.button>
<span wire:poll.5000ms='pollingStatus'>
@if ($application->status === 'running')

View File

@@ -1,14 +1,16 @@
<div>
<form class="flex flex-col gap-2 w-96" wire:submit.prevent='createGitHubApp'>
<x-inputs.input id="name" label="Name" required />
<x-inputs.input id="html_url" label="HTML Url" required />
<x-inputs.input id="api_url" label="API Url" required />
<x-inputs.input id="organization" label="Organization" />
<x-inputs.input id="custom_user" label="Custom Git User" required />
<x-inputs.input id="custom_port" label="Custom Git Port" required />
<x-inputs.input type="checkbox" id="is_system_wide" label="System Wide" />
<form wire:submit.prevent='createGitHubApp'>
<x-inputs.button type="submit">
Submit
</x-inputs.button>
<h3 class="pt-4">General</h3>
<x-inputs.input id="name" label="Name" required />
<x-inputs.input helper="If empty, your user will be used." id="organization" label="Organization" />
<h3 class="pt-4">Advanced</h3>
<x-inputs.input id="html_url" label="HTML Url" required />
<x-inputs.input id="api_url" label="API Url" required />
<x-inputs.input id="custom_user" label="Custom Git User" required />
<x-inputs.input id="custom_port" label="Custom Git Port" required />
<x-inputs.checkbox class="pt-2" id="is_system_wide" label="System Wide" />
</form>
</div>