Merge branch 'next' into main

This commit is contained in:
Marvin von Rappard
2024-12-06 06:29:35 +01:00
committed by GitHub
82 changed files with 1067 additions and 223 deletions

View File

@@ -6,7 +6,7 @@
html,
body {
@apply h-full bg-neutral-50 text-neutral-800 dark:bg-base dark:text-neutral-400;
@apply h-full bg-neutral-50 text-neutral-800 dark:bg-base dark:text-neutral-400 w-full;
}
body {
@@ -322,4 +322,4 @@ section {
.dz-button {
@apply w-full p-4 py-10 my-4 font-bold bg-white border dark:border-coolgray-400 dark:text-white dark:bg-transparent hover:dark:bg-coolgray-400;
}
}

View File

@@ -7,6 +7,7 @@
'action' => 'delete',
'content' => null,
'closeOutside' => true,
'minWidth' => '36rem',
])
<div x-data="{ modalOpen: false }" :class="{ 'z-40': modalOpen }" @keydown.window.escape="modalOpen=false"
class="relative w-auto h-auto" wire:ignore>
@@ -40,7 +41,7 @@
x-transition:leave="ease-in duration-100"
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
x-transition:leave-end="opacity-0 -translate-y-2 sm:scale-95"
class="relative w-full py-6 border rounded drop-shadow min-w-full lg:min-w-[36rem] max-w-fit bg-white border-neutral-200 dark:bg-base px-6 dark:border-coolgray-300">
class="relative w-full py-6 border rounded drop-shadow min-w-full lg:min-w-[{{ $minWidth }}] max-w-fit bg-white border-neutral-200 dark:bg-base px-6 dark:border-coolgray-300">
<div class="flex items-center justify-between pb-3">
<h3 class="text-2xl font-bold">{{ $title }}</h3>
<button @click="modalOpen=false"

View File

@@ -7,8 +7,13 @@
}
window.location.reload();
},
setZoom(zoom) {
localStorage.setItem('zoom', zoom);
window.location.reload();
},
init() {
this.full = localStorage.getItem('pageWidth');
this.zoom = localStorage.getItem('zoom');
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
const userSettings = localStorage.getItem('theme');
if (userSettings !== 'system') {
@@ -21,6 +26,7 @@
}
});
this.queryTheme();
this.checkZoom();
},
setTheme(type) {
this.theme = type;
@@ -44,6 +50,30 @@
this.theme = 'system';
document.documentElement.classList.remove('dark');
}
},
checkZoom() {
if (this.zoom === null) {
this.setZoom(100);
}
if (this.zoom === '90') {
const style = document.createElement('style');
style.textContent = `
html {
font-size: 93.75%;
}
:root {
--vh: 1vh;
}
@media (min-width: 1024px) {
html {
font-size: 87.5%;
}
}
`;
document.head.appendChild(style);
}
}
}">
<div class="flex pt-6 pb-4 pl-2">
@@ -69,7 +99,7 @@
</div>
</x-slot:title>
<div class="flex flex-col gap-1">
<div class="mb-1 font-bold border-b dark:border-coolgray-500 dark:text-white text-md">Color</div>
<div class="font-bold border-b dark:border-coolgray-500 dark:text-white text-md">Color</div>
<button @click="setTheme('dark')" class="px-1 dropdown-item-no-padding">Dark</button>
<button @click="setTheme('light')" class="px-1 dropdown-item-no-padding">Light</button>
<button @click="setTheme('system')" class="px-1 dropdown-item-no-padding">System</button>
@@ -78,6 +108,9 @@
x-show="full === 'full'">Center</button>
<button @click="switchWidth()" class="px-1 dropdown-item-no-padding"
x-show="full === 'center'">Full</button>
<div class="my-1 font-bold border-b dark:border-coolgray-500 dark:text-white text-md">Zoom</div>
<button @click="setZoom(100)" class="px-1 dropdown-item-no-padding">100%</button>
<button @click="setZoom(90)" class="px-1 dropdown-item-no-padding">90%</button>
</div>
</x-dropdown>
</div>
@@ -163,8 +196,8 @@
class="{{ request()->is('storages*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('storage.index') }}">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<g fill="none" stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2">
<path d="M4 6a8 3 0 1 0 16 0A8 3 0 1 0 4 6" />
<path d="M4 6v6a8 3 0 0 0 16 0V6" />
<path d="M4 12v6a8 3 0 0 0 16 0v-6" />

View File

@@ -17,7 +17,8 @@
@if (isEmailEnabled($team) && auth()->user()->isAdminFromSession() && isTestEmailEnabled($team))
<x-modal-input buttonTitle="Send Test Email" title="Send Test Email">
<form wire:submit.prevent="sendTestEmail" class="flex flex-col w-full gap-2">
<x-forms.input wire:model="testEmailAddress" placeholder="test@example.com" id="testEmailAddress" label="Recipients" required />
<x-forms.input wire:model="testEmailAddress" placeholder="test@example.com" id="testEmailAddress"
label="Recipients" required />
<x-forms.button type="submit" @click="modalOpen=false">
Send Email
</x-forms.button>
@@ -62,8 +63,11 @@
<div class="flex flex-col w-full gap-2 xl:flex-row">
<x-forms.input required id="smtpHost" placeholder="smtp.mailgun.org" label="Host" />
<x-forms.input required id="smtpPort" placeholder="587" label="Port" />
<x-forms.input id="smtpEncryption" helper="If SMTP uses SSL, set it to 'tls'."
placeholder="tls" label="Encryption" />
<x-forms.select id="smtpEncryption" label="Encryption">
<option value="tls">TLS</option>
<option value="ssl">SSL</option>
<option value="none">None</option>
</x-forms.select>
</div>
<div class="flex flex-col w-full gap-2 xl:flex-row">
<x-forms.input id="smtpUsername" label="SMTP Username" />

View File

@@ -13,6 +13,8 @@
helper="Allow to automatically deploy Preview Deployments for all opened PR's.<br><br>Closing a PR will delete Preview Deployments."
instantSave id="isPreviewDeploymentsEnabled" label="Preview Deployments" />
@endif
<x-forms.checkbox helper="Disable Docker build cache on every deployment." instantSave id="disableBuildCache"
label="Disable Build Cache" />
<x-forms.checkbox
helper="Your application will be available only on https if your domain starts with https://..."
instantSave id="isForceHttpsEnabled" label="Force Https" />

View File

@@ -32,7 +32,7 @@
@forelse ($deployments as $deployment)
<div @class([
'dark:bg-coolgray-100 p-2 border-l-2 transition-colors hover:no-underline box-without-bg-without-border bg-white flex-col cursor-pointer dark:hover:text-neutral-400 dark:hover:bg-coolgray-200',
'border-warning border-dashed ' =>
'border-white border-dashed ' =>
data_get($deployment, 'status') === 'in_progress' ||
data_get($deployment, 'status') === 'cancelled-by-user',
'border-error border-dashed ' =>

View File

@@ -19,7 +19,7 @@
},
toggleScroll() {
this.alwaysScroll = !this.alwaysScroll;
if (this.alwaysScroll) {
this.intervalId = setInterval(() => {
const screen = document.getElementById('screen');
@@ -58,30 +58,34 @@
<div @if ($isKeepAliveOn) wire:poll.2000ms="polling" @endif
class="flex flex-col-reverse w-full p-2 px-4 mt-4 overflow-y-auto bg-white dark:text-white dark:bg-coolgray-100 scrollbar dark:border-coolgray-300"
:class="fullscreen ? '' : 'min-h-14 max-h-[40rem] border border-dotted rounded'">
<div :class="fullscreen ? 'fixed' : 'absolute'" class="top-4 right-6">
<div :class="fullscreen ? 'fixed' : 'absolute'" class="top-2 right-3">
<div class="flex justify-end gap-4 fixed -translate-x-full">
<button title="Toggle timestamps" x-on:click="showTimestamps = !showTimestamps">
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="none"
stroke="currentColor" stroke-width="2">
<svg class="w-5 h-5 opacity-30 hover:opacity-100" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor"
stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round"
d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
</button>
<button title="Go Top" x-show="fullscreen" x-on:click="goTop">
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<svg class="w-5 h-5 opacity-30 hover:opacity-100" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path fill="none" stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2" d="M12 5v14m4-10l-4-4M8 9l4-4" />
</svg>
</button>
<button title="Follow Logs" x-show="fullscreen" :class="alwaysScroll ? 'dark:text-warning' : ''"
x-on:click="toggleScroll">
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<svg class="w-5 h-5 opacity-30 hover:opacity-100" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path fill="none" stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2" d="M12 5v14m4-4l-4 4m-4-4l4 4" />
</svg>
</button>
<button title="Fullscreen" x-show="!fullscreen" x-on:click="makeFullscreen">
<svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<svg class="w-5 h-5 opacity-30 hover:opacity-100" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<g fill="none">
<path
d="M24 0v24H0V0h24ZM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035c-.01-.004-.019-.001-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427c-.002-.01-.009-.017-.017-.018Zm.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093c.012.004.023 0 .029-.008l.004-.014l-.034-.614c-.003-.012-.01-.02-.02-.022Zm-.715.002a.023.023 0 0 0-.027.006l-.006.014l-.034.614c0 .012.007.02.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01l-.184-.092Z" />
@@ -91,7 +95,8 @@
</svg>
</button>
<button title="Minimize" x-show="fullscreen" x-on:click="makeFullscreen">
<svg class="icon" viewBox="0 0 24 24"xmlns="http://www.w3.org/2000/svg">
<svg class="w-5 h-5 opacity-30 hover:opacity-100"
viewBox="0 0 24 24"xmlns="http://www.w3.org/2000/svg">
<path fill="none" stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2"
d="M6 14h4m0 0v4m0-4l-6 6m14-10h-4m0 0V6m0 4l6-6" />

View File

@@ -43,7 +43,7 @@
<h4 class="py-2 ">Select another Private Key</h4>
<div class="flex flex-wrap gap-2">
@foreach ($privateKeys as $key)
<x-forms.button wire:click.defer="setPrivateKey('{{ $key->id }}')">{{ $key->name }}
<x-forms.button wire:click="setPrivateKey('{{ $key->id }}')">{{ $key->name }}
</x-forms.button>
@endforeach
</div>

View File

@@ -169,7 +169,8 @@
}
const filtered = Object.values(items).filter(item => {
return (item.name?.toLowerCase().includes(searchLower) ||
item.description?.toLowerCase().includes(searchLower))
item.description?.toLowerCase().includes(searchLower) ||
item.slogan?.toLowerCase().includes(searchLower))
})
return isSort ? filtered.sort(sortFn) : filtered;
},

View File

@@ -15,7 +15,7 @@
volume
name, example: <span class='text-helper'>-pr-1</span>" />
@if ($resource?->build_pack !== 'dockercompose')
<x-modal-input :closeOutside="false" buttonTitle="+ Add" title="New Persistent Storage">
<x-modal-input :closeOutside="false" buttonTitle="+ Add" title="New Persistent Storage" minWidth="64rem">
<livewire:project.shared.storages.add :resource="$resource" />
</x-modal-input>
@endif

View File

@@ -1,13 +1,15 @@
<div class="flex flex-col w-full gap-2 rounded max-h-[80vh] overflow-y-auto scrollbar">
<div class="p-4">
You can add Volumes, Files and Directories to your resources here.
<form class="flex flex-col w-full gap-2 rounded" wire:submit='submitPersistentVolume'>
<div class="flex flex-col w-full gap-2 max-h-[80vh] overflow-y-auto scrollbar">
<form class="flex flex-col w-full gap-2 rounded " wire:submit='submitPersistentVolume'>
<div class="flex flex-col">
<h3>Volume Mount</h3>
@if ($isSwarm)
<h5>Swarm Mode detected: You need to set a shared volume (EFS/NFS/etc) on all the worker nodes if you
would
like to use a persistent volumes.</h5>
@endif
<div>Docker Volumes mounted to the container.</div>
</div>
@if ($isSwarm)
<h5>Swarm Mode detected: You need to set a shared volume (EFS/NFS/etc) on all the worker nodes if you
would
like to use a persistent volumes.</h5>
@endif
<div class="flex flex-col gap-2 px-2">
<x-forms.input placeholder="pv-name" id="name" label="Name" required helper="Volume name." />
@if ($isSwarm)
<x-forms.input placeholder="/root" id="host_path" label="Source Path" required
@@ -19,29 +21,39 @@
<x-forms.input placeholder="/tmp/root" id="mount_path" label="Destination Path" required
helper="Directory inside the container." />
<x-forms.button type="submit" @click="modalOpen=false">
Save
Add
</x-forms.button>
</div>
</form>
<form class="flex flex-col w-full gap-2 rounded" wire:submit='submitFileStorage'>
</form>
<form class="flex flex-col w-full gap-2 rounded py-4" wire:submit='submitFileStorage'>
<div class="flex flex-col">
<h3>File Mount</h3>
<div>Actual file mounted from the host system to the container.</div>
</div>
<div class="flex flex-col gap-2 px-2">
<x-forms.input placeholder="/etc/nginx/nginx.conf" id="file_storage_path" label="Destination Path" required
helper="File inside the container" />
helper="File location inside the container" />
<x-forms.textarea label="Content" id="file_storage_content"></x-forms.textarea>
<x-forms.button type="submit" @click="modalOpen=false">
Save
Add
</x-forms.button>
</form>
<form class="flex flex-col w-full gap-2 rounded" wire:submit='submitFileStorageDirectory'>
</div>
</form>
<form class="flex flex-col w-full gap-2 rounded" wire:submit='submitFileStorageDirectory'>
<div class="flex flex-col">
<h3>Directory Mount</h3>
<div>Directory mounted from the host system to the container.</div>
</div>
<div class="flex flex-col gap-2 px-2">
<x-forms.input placeholder="{{ application_configuration_dir() }}/{{ $resource->uuid }}/etc/nginx"
id="file_storage_directory_source" label="Source Directory" required
helper="Directory on the host system." />
<x-forms.input placeholder="/etc/nginx" id="file_storage_directory_destination"
label="Destination Directory" required helper="Directory inside the container." />
<x-forms.button type="submit" @click="modalOpen=false">
Save
Add
</x-forms.button>
</form>
</div>
</div>
</form>
</div>

View File

@@ -88,7 +88,7 @@
<div class="w-full" x-data="{
open: false,
search: '{{ $serverTimezone ?: '' }}',
timezones: @js($timezones),
timezones: @js($this->timezones),
placeholder: '{{ $serverTimezone ? 'Search timezone...' : 'Select Server Timezone' }}',
init() {
this.$watch('search', value => {

View File

@@ -33,8 +33,11 @@
<div class="flex flex-col w-full gap-2 xl:flex-row">
<x-forms.input required id="smtpHost" placeholder="smtp.mailgun.org" label="Host" />
<x-forms.input required id="smtpPort" placeholder="587" label="Port" />
<x-forms.input id="smtpEncryption" helper="If SMTP uses SSL, set it to 'tls'." placeholder="tls"
label="Encryption" />
<x-forms.select id="smtpEncryption" label="Encryption">
<option value="tls">TLS</option>
<option value="ssl">SSL</option>
<option value="none">None</option>
</x-forms.select>
</div>
<div class="flex flex-col w-full gap-2 xl:flex-row">
<x-forms.input id="smtpUsername" label="SMTP Username" />

View File

@@ -23,7 +23,7 @@
<div class="w-full" x-data="{
open: false,
search: '{{ $settings->instance_timezone ?: '' }}',
timezones: @js($timezones),
timezones: @js($this->timezones),
placeholder: '{{ $settings->instance_timezone ? 'Search timezone...' : 'Select Server Timezone' }}',
init() {
this.$watch('search', value => {

View File

@@ -58,7 +58,18 @@
@else
<div class="flex flex-col gap-2">
<div class="flex gap-2">
<x-forms.input id="github_app.name" label="App Name" disabled />
<div class="flex items-end gap-2 w-full">
<x-forms.input id="github_app.name" label="App Name" disabled />
<x-forms.button wire:click.prevent="updateGithubAppName" class="bg-coollabs">
Sync Name
</x-forms.button>
<a href="{{ $this->getGithubAppNameUpdatePath() }}">
<x-forms.button>
Rename
<x-external-link />
</x-forms.button>
</a>
</div>
<x-forms.input id="github_app.organization" label="Organization" disabled
placeholder="If empty, personal user will be used" />
</div>

View File

@@ -1,6 +1,6 @@
<x-forms.select wire:model.live="selectedTeamId" label="Current Team">
<option value="default" disabled selected>Switch team</option>
@foreach (auth()->user()->teams as $team)
<option value="{{ $team->id }}">{{ $team->name }}</option>
<option value="{{ $team->id }}">{{ $team->name }}</option>
@endforeach
</x-forms.select>