Merge branch 'ui' into next

This commit is contained in:
Andras Bacsai
2022-09-19 12:06:00 +02:00
89 changed files with 3161 additions and 3325 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -3,33 +3,35 @@ import Cookies from 'js-cookie';
export function getAPIUrl() { export function getAPIUrl() {
if (GITPOD_WORKSPACE_URL) { if (GITPOD_WORKSPACE_URL) {
const { href } = new URL(GITPOD_WORKSPACE_URL) const { href } = new URL(GITPOD_WORKSPACE_URL);
const newURL = href.replace('https://', 'https://3001-').replace(/\/$/, '') const newURL = href.replace('https://', 'https://3001-').replace(/\/$/, '');
return newURL return newURL;
} }
if (CODESANDBOX_HOST) { if (CODESANDBOX_HOST) {
return `https://${CODESANDBOX_HOST.replace(/\$PORT/,'3001')}` return `https://${CODESANDBOX_HOST.replace(/\$PORT/, '3001')}`;
} }
return dev ? 'http://localhost:3001' : 'http://localhost:3000'; return dev
? 'http://localhost:3001'
: 'http://localhost:3000';
} }
export function getWebhookUrl(type: string) { export function getWebhookUrl(type: string) {
if (GITPOD_WORKSPACE_URL) { if (GITPOD_WORKSPACE_URL) {
const { href } = new URL(GITPOD_WORKSPACE_URL) const { href } = new URL(GITPOD_WORKSPACE_URL);
const newURL = href.replace('https://', 'https://3001-').replace(/\/$/, '') const newURL = href.replace('https://', 'https://3001-').replace(/\/$/, '');
if (type === 'github') { if (type === 'github') {
return `${newURL}/webhooks/github/events` return `${newURL}/webhooks/github/events`;
} }
if (type === 'gitlab') { if (type === 'gitlab') {
return `${newURL}/webhooks/gitlab/events` return `${newURL}/webhooks/gitlab/events`;
} }
} }
if (CODESANDBOX_HOST) { if (CODESANDBOX_HOST) {
const newURL = `https://${CODESANDBOX_HOST.replace(/\$PORT/,'3001')}` const newURL = `https://${CODESANDBOX_HOST.replace(/\$PORT/, '3001')}`;
if (type === 'github') { if (type === 'github') {
return `${newURL}/webhooks/github/events` return `${newURL}/webhooks/github/events`;
} }
if (type === 'gitlab') { if (type === 'gitlab') {
return `${newURL}/webhooks/gitlab/events` return `${newURL}/webhooks/gitlab/events`;
} }
} }
return `https://webhook.site/0e5beb2c-4e9b-40e2-a89e-32295e570c21/events`; return `https://webhook.site/0e5beb2c-4e9b-40e2-a89e-32295e570c21/events`;
@@ -103,7 +105,11 @@ async function send({
return {}; return {};
} }
if (!response.ok) { if (!response.ok) {
if (response.status === 401 && !path.startsWith('https://api.github') && !path.includes('/v4/user')) { if (
response.status === 401 &&
!path.startsWith('https://api.github') &&
!path.includes('/v4/user')
) {
Cookies.remove('token'); Cookies.remove('token');
} }

View File

@@ -13,8 +13,9 @@
export let id: string; export let id: string;
export let name: string; export let name: string;
export let placeholder = ''; export let placeholder = '';
export let inputStyle = '';
let disabledClass = 'bg-coolback disabled:bg-coolblack'; let disabledClass = 'bg-coolback disabled:bg-coolblack w-full';
let isHttps = browser && window.location.protocol === 'https:'; let isHttps = browser && window.location.protocol === 'https:';
function copyToClipboard() { function copyToClipboard() {
@@ -32,6 +33,7 @@
{#if !isPasswordField || showPassword} {#if !isPasswordField || showPassword}
{#if textarea} {#if textarea}
<textarea <textarea
style={inputStyle}
rows="5" rows="5"
class={disabledClass} class={disabledClass}
class:pr-10={true} class:pr-10={true}
@@ -47,6 +49,7 @@
> >
{:else} {:else}
<input <input
style={inputStyle}
class={disabledClass} class={disabledClass}
type="text" type="text"
class:pr-10={true} class:pr-10={true}
@@ -63,6 +66,7 @@
{/if} {/if}
{:else} {:else}
<input <input
style={inputStyle}
class={disabledClass} class={disabledClass}
class:pr-10={true} class:pr-10={true}
class:pr-20={value && isHttps} class:pr-20={value && isHttps}

View File

@@ -10,7 +10,7 @@
.slice(-16); .slice(-16);
</script> </script>
<a {id} href={url} target="_blank" class="icons inline-block text-pink-500 cursor-pointer text-xs"> <a {id} href={url} target="_blank" class="icons inline-block cursor-pointer text-xs mx-2">
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6" class="w-6 h-6"

View File

@@ -10,17 +10,17 @@
}); });
</script> </script>
<div {id} class="inline-block mx-2 text-pink-500 cursor-pointer" bind:this={self}> <div {id} class="inline-block mx-2 cursor-pointer" bind:this={self}>
<svg <svg
fill="none" fill="none"
height="18" height="14"
shape-rendering="geometricPrecision" shape-rendering="geometricPrecision"
stroke="currentColor" stroke="currentColor"
stroke-linecap="round" stroke-linecap="round"
stroke-linejoin="round" stroke-linejoin="round"
stroke-width="1.5" stroke-width="1.4"
viewBox="0 0 24 24" viewBox="0 0 24 24"
width="18" width="14"
><path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z" /><path ><path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z" /><path
d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3" d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3"
/><circle cx="12" cy="17" r=".5" /> /><circle cx="12" cy="17" r=".5" />

View File

@@ -15,9 +15,13 @@
<div class="flex items-center py-4 pr-8"> <div class="flex items-center py-4 pr-8">
<div class="flex w-96 flex-col"> <div class="flex w-96 flex-col">
<div class="text-xs font-bold text-stone-100 md:text-base"> <!-- svelte-ignore a11y-label-has-associated-control -->
{title}<Explaner explanation={description} /> <label>
</div> {title}
{#if description && description !== ''}
<Explaner explanation={description} />
{/if}
</label>
</div> </div>
</div> </div>
<div class:text-center={isCenter} class="flex justify-center"> <div class:text-center={isCenter} class="flex justify-center">

View File

@@ -2,6 +2,11 @@
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
export let type = 'info'; export let type = 'info';
function success() {
if (type === 'success') {
return 'bg-gradient-to-r from-coollabs to-pink-500';
}
}
</script> </script>
<div <div
@@ -10,8 +15,7 @@
on:focus={() => dispatch('pause')} on:focus={() => dispatch('pause')}
on:mouseout={() => dispatch('resume')} on:mouseout={() => dispatch('resume')}
on:blur={() => dispatch('resume')} on:blur={() => dispatch('resume')}
class="alert shadow-lg text-white rounded hover:scale-105 transition-all duration-100 cursor-pointer" class={`alert shadow-lg text-white hover:scale-105 transition-all duration-100 cursor-pointer rounded ${success()}`}
class:bg-coollabs={type === 'success'}
class:alert-error={type === 'error'} class:alert-error={type === 'error'}
class:alert-info={type === 'info'} class:alert-info={type === 'info'}
> >

View File

@@ -1,5 +1,4 @@
<script lang="ts"> <script lang="ts">
import { fade } from 'svelte/transition';
import Toast from './Toast.svelte'; import Toast from './Toast.svelte';
import { dismissToast, pauseToast, resumeToast, toasts } from '$lib/store'; import { dismissToast, pauseToast, resumeToast, toasts } from '$lib/store';
@@ -7,9 +6,9 @@
{#if $toasts} {#if $toasts}
<section> <section>
<article class="toast toast-top toast-end rounded-none" role="alert" transition:fade> <article class="toast toast-top toast-end rounded-none px-10" role="alert" >
{#each $toasts as toast (toast.id)} {#each $toasts as toast (toast.id)}
<Toast <Toast
type={toast.type} type={toast.type}
on:resume={() => resumeToast(toast.id)} on:resume={() => resumeToast(toast.id)}
on:pause={() => pauseToast(toast.id)} on:pause={() => pauseToast(toast.id)}

View File

@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { Tooltip } from 'flowbite-svelte'; import { Tooltip } from 'flowbite-svelte';
export let placement = 'bottom'; export let placement = 'bottom';
export let color = 'bg-coollabs text-left'; export let color = 'bg-coolgray-300 font-thin text-left';
export let triggeredBy = '#tooltip-default'; export let triggeredBy = '#tooltip-default';
</script> </script>

View File

@@ -83,7 +83,7 @@
id="update" id="update"
disabled={updateStatus.success === false} disabled={updateStatus.success === false}
on:click={update} on:click={update}
class="icons bg-gradient-to-r from-purple-500 via-pink-500 to-red-500 text-white duration-75 hover:scale-105" class="icons bg-gradient-to-r from-coollabs to-pink-500 text-white duration-75 hover:scale-105"
> >
{#if updateStatus.loading} {#if updateStatus.loading}
<svg <svg

View File

@@ -79,12 +79,12 @@
BETA BETA
</div> </div>
{/if} {/if}
<div class="w-full flex flex-row space-x-4"> <div class="w-full flex flex-col lg:flex-row space-y-4 lg:space-y-0 space-x-4">
<div class="flex flex-col"> <div class="flex flex-col">
<h1 class="font-bold text-lg lg:text-xl truncate"> <h1 class="font-bold text-lg lg:text-xl truncate">
{server.name} {server.name}
</h1> </h1>
<div class="text-xs "> <div class="text-xs">
{#if server?.remoteIpAddress} {#if server?.remoteIpAddress}
<h2>{server?.remoteIpAddress}</h2> <h2>{server?.remoteIpAddress}</h2>
{:else} {:else}

View File

@@ -9,15 +9,8 @@
viewBox="0 0 309.88 252.72" viewBox="0 0 309.88 252.72"
class={isAbsolute ? 'absolute top-0 left-0 -m-5 h-12 w-12 ' : 'mx-auto w-8 h-8'} class={isAbsolute ? 'absolute top-0 left-0 -m-5 h-12 w-12 ' : 'mx-auto w-8 h-8'}
> >
<defs>
<style>
.cls-1 {
fill: #fff;
}
</style>
</defs>
<path <path
class="cls-1" fill="#fff"
d="M316,10.05a4.2,4.2,0,0,0-2.84-1c-2.84,0-6.5,1.92-8.46,3l-.79.4a26.81,26.81,0,0,1-10.57,2.66c-3.76.12-7,.34-11.22.77-25,2.58-36.15,21.74-46.89,40.27-5.84,10.08-11.88,20.5-20.16,28.57a55.71,55.71,0,0,1-5.46,4.63c-8.57,6.39-19.33,10.9-27.74,14.12-8.07,3.08-16.86,5.85-25.37,8.53-7.78,2.45-15.14,4.76-21.9,7.28-3.05,1.13-5.64,2-7.93,2.76-6.15,2-10.6,3.53-17.08,8-2.53,1.73-5.07,3.6-6.8,5a71.26,71.26,0,0,0-13.54,14.27A84.81,84.81,0,0,1,77.88,163c-1.36,1.34-3.8,2-7.43,2-4.27,0-9.43-.88-14.91-1.81s-11.46-2-16.46-2c-4.07,0-7.17.66-9.5,2,0,0-3.9,2.28-5.56,5.23l1.62.73a33.56,33.56,0,0,1,6.93,5,33.68,33.68,0,0,0,7.19,5.12A6.37,6.37,0,0,1,42,180.72c-.69,1-1.69,2.29-2.74,3.67-5.77,7.55-9.13,12.32-7.2,14.92a6,6,0,0,0,3,.68c12.59,0,19.34-3.27,27.9-7.41,2.47-1.2,5-2.44,8-3.7,5-2.17,10.38-5.63,16.08-9.29,7.55-4.85,15.36-9.87,22.92-12.3a62.3,62.3,0,0,1,19.23-2.7c8,0,16.42,1.07,24.54,2.11,6.06.78,12.32,1.58,18.47,2,2.39.14,4.6.21,6.76.21a78.48,78.48,0,0,0,8.61-.45l.68-.24c4.32-2.65,6.34-8.34,8.29-13.84,1.26-3.54,2.32-6.72,4-8.74a2.06,2.06,0,0,1,.33-.27.4.4,0,0,1,.49.08.25.25,0,0,1,0,.16c-1,21.51-9.67,35.16-18.42,47.3L177,199.14s8.18,0,12.84-1.8c17-5.08,29.84-16.28,39.18-34.14a144.39,144.39,0,0,0,6.16-14.09c.16-.4,1.64-1.14,1.49.93,0,.61-.08,1.29-.13,2h0c0,.42-.06.85-.08,1.28-.25,3-1,9.34-1,9.34l5.25-2.81c12.66-8,22.42-24.14,29.82-49.25,3.09-10.46,5.34-20.85,7.33-30,2.38-11,4.43-20.43,6.78-24.09,3.69-5.74,9.32-9.62,14.77-13.39.75-.51,1.49-1,2.22-1.54,6.86-4.81,13.67-10.36,15.16-20.71l0-.23C317.93,12.92,317,11,316,10.05Z" d="M316,10.05a4.2,4.2,0,0,0-2.84-1c-2.84,0-6.5,1.92-8.46,3l-.79.4a26.81,26.81,0,0,1-10.57,2.66c-3.76.12-7,.34-11.22.77-25,2.58-36.15,21.74-46.89,40.27-5.84,10.08-11.88,20.5-20.16,28.57a55.71,55.71,0,0,1-5.46,4.63c-8.57,6.39-19.33,10.9-27.74,14.12-8.07,3.08-16.86,5.85-25.37,8.53-7.78,2.45-15.14,4.76-21.9,7.28-3.05,1.13-5.64,2-7.93,2.76-6.15,2-10.6,3.53-17.08,8-2.53,1.73-5.07,3.6-6.8,5a71.26,71.26,0,0,0-13.54,14.27A84.81,84.81,0,0,1,77.88,163c-1.36,1.34-3.8,2-7.43,2-4.27,0-9.43-.88-14.91-1.81s-11.46-2-16.46-2c-4.07,0-7.17.66-9.5,2,0,0-3.9,2.28-5.56,5.23l1.62.73a33.56,33.56,0,0,1,6.93,5,33.68,33.68,0,0,0,7.19,5.12A6.37,6.37,0,0,1,42,180.72c-.69,1-1.69,2.29-2.74,3.67-5.77,7.55-9.13,12.32-7.2,14.92a6,6,0,0,0,3,.68c12.59,0,19.34-3.27,27.9-7.41,2.47-1.2,5-2.44,8-3.7,5-2.17,10.38-5.63,16.08-9.29,7.55-4.85,15.36-9.87,22.92-12.3a62.3,62.3,0,0,1,19.23-2.7c8,0,16.42,1.07,24.54,2.11,6.06.78,12.32,1.58,18.47,2,2.39.14,4.6.21,6.76.21a78.48,78.48,0,0,0,8.61-.45l.68-.24c4.32-2.65,6.34-8.34,8.29-13.84,1.26-3.54,2.32-6.72,4-8.74a2.06,2.06,0,0,1,.33-.27.4.4,0,0,1,.49.08.25.25,0,0,1,0,.16c-1,21.51-9.67,35.16-18.42,47.3L177,199.14s8.18,0,12.84-1.8c17-5.08,29.84-16.28,39.18-34.14a144.39,144.39,0,0,0,6.16-14.09c.16-.4,1.64-1.14,1.49.93,0,.61-.08,1.29-.13,2h0c0,.42-.06.85-.08,1.28-.25,3-1,9.34-1,9.34l5.25-2.81c12.66-8,22.42-24.14,29.82-49.25,3.09-10.46,5.34-20.85,7.33-30,2.38-11,4.43-20.43,6.78-24.09,3.69-5.74,9.32-9.62,14.77-13.39.75-.51,1.49-1,2.22-1.54,6.86-4.81,13.67-10.36,15.16-20.71l0-.23C317.93,12.92,317,11,316,10.05Z"
transform="translate(-7.45 -9.1)" transform="translate(-7.45 -9.1)"
/> />

View File

@@ -5,7 +5,7 @@
<svg <svg
viewBox="0 0 700 240" viewBox="0 0 700 240"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
class={isAbsolute ? 'w-36 absolute top-0 left-0 -m-3 -mt-5' : 'w-28 h-28 mx-auto'} class={isAbsolute ? 'w-36 absolute top-0 left-0 -m-3 -mt-5' : 'w-full h-10 mx-auto'}
><path fill="#FDBC3D" d="m90.694 107.498-.981.39-20.608 8.23 6.332 6.547z" /><path ><path fill="#FDBC3D" d="m90.694 107.498-.981.39-20.608 8.23 6.332 6.547z" /><path
fill="#8EC63F" fill="#8EC63F"
d="M61.139 77.914 46.632 93 56.9 103.547c8.649-7.169 17.832-10.502 18.653-10.789L61.139 77.914z" d="M61.139 77.914 46.632 93 56.9 103.547c8.649-7.169 17.832-10.502 18.653-10.789L61.139 77.914z"

View File

@@ -4,7 +4,7 @@
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
class={isAbsolute ? 'w-16 h-16 absolute top-0 left-0 -m-7' : 'w-12 h-12 mx-auto'} class={isAbsolute ? 'w-16 h-16 absolute top-0 left-0 -m-7' : 'w-10 h-10 mx-auto'}
version="1.1" version="1.1"
viewBox="0 0 300 300" viewBox="0 0 300 300"
><linearGradient ><linearGradient

View File

@@ -88,7 +88,7 @@
"removing": "Removing...", "removing": "Removing...",
"remove_domain": "Remove domain", "remove_domain": "Remove domain",
"public_port_range": "Public Port Range", "public_port_range": "Public Port Range",
"public_port_range_explainer": "Ports used to expose databases/services/internal services.<br> Add them to your firewall (if applicable).<br><br>You can specify a range of ports, eg: <span class='text-settings font-bold'>9000-9100</span>", "public_port_range_explainer": "Ports used to expose databases/services/internal services.<br> Add them to your firewall (if applicable).<br><br>You can specify a range of ports, eg: <span class='text-settings '>9000-9100</span>",
"no_actions_available": "No actions available", "no_actions_available": "No actions available",
"admin_api_key": "Admin API key" "admin_api_key": "Admin API key"
}, },
@@ -144,8 +144,8 @@
}, },
"preview": { "preview": {
"need_during_buildtime": "Need during buildtime?", "need_during_buildtime": "Need during buildtime?",
"setup_secret_app_first": "You can add secrets to PR/MR deployments. Please add secrets to the application first. <br>Useful for creating <span class='text-green-500 font-bold'>staging</span> environments.", "setup_secret_app_first": "You can add secrets to PR/MR deployments. Please add secrets to the application first. <br>Useful for creating <span class='text-settings '>staging</span> environments.",
"values_overwriting_app_secrets": "These values overwrite application secrets in PR/MR deployments. Useful for creating <span class='text-green-500 font-bold'>staging</span> environments.", "values_overwriting_app_secrets": "These values overwrite application secrets in PR/MR deployments. Useful for creating <span class='text-settings '>staging</span> environments.",
"redeploy": "Redeploy", "redeploy": "Redeploy",
"no_previews_available": "No previews available" "no_previews_available": "No previews available"
}, },
@@ -159,7 +159,7 @@
"storage_saved": "Storage saved.", "storage_saved": "Storage saved.",
"storage_updated": "Storage updated.", "storage_updated": "Storage updated.",
"storage_deleted": "Storage deleted.", "storage_deleted": "Storage deleted.",
"persistent_storage_explainer": "You can specify any folder that you want to be persistent across deployments.<br><span class='text-green-500 font-bold'>/example</span> means it will preserve <span class='text-green-500 font-bold'>/app/example</span> in the container as <span class='text-green-500 font-bold'>/app</span> is <span class='text-green-500 font-bold'>the root directory</span> for your application.<br><br>This is useful for storing data such as a <span class='text-green-500 font-bold'>database (SQLite)</span> or a <span class='text-green-500 font-bold'>cache</span>." "persistent_storage_explainer": "You can specify any folder that you want to be persistent across deployments.<br><span class='text-settings '>/example</span> means it will preserve <span class='text-settings '>/app/example</span> in the container as <span class='text-settings '>/app</span> is <span class='text-settings '>the root directory</span> for your application.<br><br>This is useful for storing data such as a <span class='text-settings '>database (SQLite)</span> or a <span class='text-settings '>cache</span>."
}, },
"deployment_queued": "Deployment queued.", "deployment_queued": "Deployment queued.",
"confirm_to_delete": "Are you sure you would like to delete '{{name}}'?", "confirm_to_delete": "Are you sure you would like to delete '{{name}}'?",
@@ -194,14 +194,14 @@
"application": "Application", "application": "Application",
"url_fqdn": "URL (FQDN)", "url_fqdn": "URL (FQDN)",
"domain_fqdn": "Domain (FQDN)", "domain_fqdn": "Domain (FQDN)",
"https_explainer": "If you specify <span class='text-green-500 font-bold'>https</span>, the application will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-green-500 font-bold'>www</span>, the application will be redirected (302) from non-www and vice versa.<br><br>To modify the domain, you must first stop the application.<br><br><span class='text-white font-bold'>You must set your DNS to point to the server IP in advance.</span>", "https_explainer": "If you specify <span class='text-settings '>https</span>, the application will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-settings '>www</span>, the application will be redirected (302) from non-www and vice versa.<br><br>To modify the domain, you must first stop the application.<br><br><span class='text-white '>You must set your DNS to point to the server IP in advance.</span>",
"ssl_www_and_non_www": "Generate SSL for www and non-www?", "ssl_www_and_non_www": "Generate SSL for www and non-www?",
"ssl_explainer": "It will generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-green-500'>both DNS entries</span> set in advance.<br><br>Useful if you expect to have visitors on both.", "ssl_explainer": "It will generate certificates for both www and non-www. <br>You need to have <span class=' text-settings'>both DNS entries</span> set in advance.<br><br>Useful if you expect to have visitors on both.",
"install_command": "Install Command", "install_command": "Install Command",
"build_command": "Build Command", "build_command": "Build Command",
"start_command": "Start Command", "start_command": "Start Command",
"directory_to_use_explainer": "Directory to use as the base for all commands.<br>Could be useful with <span class='text-green-500 font-bold'>monorepos</span>.", "directory_to_use_explainer": "Directory to use as the base for all commands.<br>Could be useful with <span class='text-settings '>monorepos</span>.",
"publish_directory_explainer": "Directory containing all the assets for deployment. <br> For example: <span class='text-green-500 font-bold'>dist</span>,<span class='text-green-500 font-bold'>_site</span> or <span class='text-green-500 font-bold'>public</span>.", "publish_directory_explainer": "Directory containing all the assets for deployment. <br> For example: <span class='text-settings '>dist</span>,<span class='text-settings '>_site</span> or <span class='text-settings '>public</span>.",
"features": "Features", "features": "Features",
"enable_automatic_deployment": "Enable Automatic Deployment", "enable_automatic_deployment": "Enable Automatic Deployment",
"enable_auto_deploy_webhooks": "Enable automatic deployment through webhooks.", "enable_auto_deploy_webhooks": "Enable automatic deployment through webhooks.",
@@ -209,7 +209,7 @@
"expose_a_port": "Expose a port", "expose_a_port": "Expose a port",
"enable_preview_deploy_mr_pr_requests": "Enable preview deployments from pull or merge requests.", "enable_preview_deploy_mr_pr_requests": "Enable preview deployments from pull or merge requests.",
"debug_logs": "Debug Logs", "debug_logs": "Debug Logs",
"enable_debug_log_during_build": "Enable debug logs during build phase.<br><span class='text-settings font-bold'>Sensitive information</span> could be visible and saved in logs.", "enable_debug_log_during_build": "Enable debug logs during build phase.<br><span class='text-settings '>Sensitive information</span> could be visible and saved in logs.",
"cant_activate_auto_deploy_without_repo": "Cannot activate automatic deployments until only one application is defined for this repository / branch.", "cant_activate_auto_deploy_without_repo": "Cannot activate automatic deployments until only one application is defined for this repository / branch.",
"no_applications_found": "No applications found", "no_applications_found": "No applications found",
"secret__batch_dot_env": "Paste .env file", "secret__batch_dot_env": "Paste .env file",
@@ -223,7 +223,7 @@
"set_public": "Set it public", "set_public": "Set it public",
"warning_database_public": "Your database will be reachable over the internet. <br>Take security seriously in this case!", "warning_database_public": "Your database will be reachable over the internet. <br>Take security seriously in this case!",
"change_append_only_mode": "Change append only mode", "change_append_only_mode": "Change append only mode",
"warning_append_only": "Useful if you would like to restore redis data from a backup.<br><span class='font-bold text-white'>Database restart is required.</span>", "warning_append_only": "Useful if you would like to restore redis data from a backup.<br><span class=' text-white'>Database restart is required.</span>",
"select_database_type": "Select a Database type", "select_database_type": "Select a Database type",
"select_database_version": "Select a Database version", "select_database_version": "Select a Database version",
"confirm_stop": "Are you sure you would like to stop {{name}}?", "confirm_stop": "Are you sure you would like to stop {{name}}?",
@@ -275,7 +275,7 @@
"application_id": "Application ID", "application_id": "Application ID",
"group_name": "Group Name", "group_name": "Group Name",
"oauth_id": "OAuth ID", "oauth_id": "OAuth ID",
"oauth_id_explainer": "The OAuth ID is the unique identifier of the GitLab application. <br>You can find it <span class='font-bold text-settings' >in the URL</span> of your GitLab OAuth Application.", "oauth_id_explainer": "The OAuth ID is the unique identifier of the GitLab application. <br>You can find it <span class=' text-settings' >in the URL</span> of your GitLab OAuth Application.",
"register_oauth_gitlab": "Register new OAuth application on GitLab", "register_oauth_gitlab": "Register new OAuth application on GitLab",
"gitlab": { "gitlab": {
"self_hosted": "Instance-wide application (self-hosted)", "self_hosted": "Instance-wide application (self-hosted)",
@@ -290,7 +290,7 @@
}, },
"services": { "services": {
"all_email_verified": "All emails are verified. You can login now.", "all_email_verified": "All emails are verified. You can login now.",
"generate_www_non_www_ssl": "It will generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-pink-600'>both DNS entries</span> set in advance.<br><br>Service needs to be restarted." "generate_www_non_www_ssl": "It will generate certificates for both www and non-www. <br>You need to have <span class='text-settings'>both DNS entries</span> set in advance.<br><br>Service needs to be restarted."
}, },
"service": { "service": {
"stop_service": "Stop", "stop_service": "Stop",
@@ -306,15 +306,15 @@
"change_language": "Change Language", "change_language": "Change Language",
"permission_denied": "You do not have permission to do this. \\nAsk an admin to modify your permissions.", "permission_denied": "You do not have permission to do this. \\nAsk an admin to modify your permissions.",
"domain_removed": "Domain removed", "domain_removed": "Domain removed",
"ssl_explainer": "If you specify <span class='text-settings font-bold'>https</span>, Coolify will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-settings font-bold'>www</span>, Coolify will be redirected (302) from non-www and vice versa.<br><br><span class='text-settings font-bold'>WARNING:</span> If you change an already set domain, it will break webhooks and other integrations! You need to manually update them.", "ssl_explainer": "If you specify <span class='text-settings'>https</span>, Coolify will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-settings '>www</span>, Coolify will be redirected (302) from non-www and vice versa.<br><br><span class='text-settings '>WARNING:</span> If you change an already set domain, it will break webhooks and other integrations! You need to manually update them.",
"must_remove_domain_before_changing": "Must remove the domain before you can change this setting.", "must_remove_domain_before_changing": "Must remove the domain before you can change this setting.",
"registration_allowed": "Registration allowed?", "registration_allowed": "Registration allowed?",
"registration_allowed_explainer": "Allow further registrations to the application. <br>It's turned off after the first registration.", "registration_allowed_explainer": "Allow further registrations to the application. <br>It's turned off after the first registration.",
"coolify_proxy_settings": "Coolify Proxy Settings", "coolify_proxy_settings": "Coolify Proxy Settings",
"credential_stat_explainer": "Credentials for <a class=\"text-white font-bold\" href=\"{{link}}\" target=\"_blank\">stats</a> page.", "credential_stat_explainer": "Credentials for <a class=\"text-white \" href=\"{{link}}\" target=\"_blank\">stats</a> page.",
"auto_update_enabled": "Auto update enabled?", "auto_update_enabled": "Auto update enabled?",
"auto_update_enabled_explainer": "Enable automatic updates for Coolify. It will be done automatically behind the scenes, if there is no build process running.", "auto_update_enabled_explainer": "Enable automatic updates for Coolify. It will be done automatically behind the scenes, if there is no build process running.",
"generate_www_non_www_ssl": "It will generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-settings'>both DNS entries</span> set in advance.", "generate_www_non_www_ssl": "It will generate certificates for both www and non-www. <br>You need to have <span class=' text-settings'>both DNS entries</span> set in advance.",
"is_dns_check_enabled": "DNS check enabled?", "is_dns_check_enabled": "DNS check enabled?",
"is_dns_check_enabled_explainer": "You can disable DNS check before creating SSL certificates.<br><br>Turning it off is useful when Coolify is behind a reverse proxy or tunnel." "is_dns_check_enabled_explainer": "You can disable DNS check before creating SSL certificates.<br><br>Turning it off is useful when Coolify is behind a reverse proxy or tunnel."
}, },
@@ -324,9 +324,9 @@
"delete": "Delete", "delete": "Delete",
"member": "member(s)", "member": "member(s)",
"root": "(root)", "root": "(root)",
"invited_with_permissions": "Invited to <span class=\"font-bold text-pink-600\">{{teamName}}</span> with <span class=\"font-bold text-rose-600\">{{permission}}</span> permission.", "invited_with_permissions": "Invited to <span class=\" text-settings\">{{teamName}}</span> with <span class=\" text-rose-600\">{{permission}}</span> permission.",
"members": "Members", "members": "Members",
"root_team_explainer": "This is the <span class='text-red-500 font-bold'>root</span> team. That means members of this group can manage instance wide settings and have all the priviliges in Coolify (imagine like root user on Linux).", "root_team_explainer": "This is the <span class='text-red-500 '>root</span> team. That means members of this group can manage instance wide settings and have all the priviliges in Coolify (imagine like root user on Linux).",
"permission": "Permission", "permission": "Permission",
"you": "(You)", "you": "(You)",
"promote_to": "Promote to {{grade}}", "promote_to": "Promote to {{grade}}",

View File

@@ -16,7 +16,7 @@
} }
</script> </script>
<div class="dropdown dropdown-hover"> <div class="dropdown dropdown-bottom">
<slot> <slot>
<label for="new" tabindex="0" class="btn btn-square btn-sm bg-coollabs"> <label for="new" tabindex="0" class="btn btn-square btn-sm bg-coollabs">
<svg <svg

View File

@@ -107,10 +107,11 @@
</script> </script>
<svelte:head> <svelte:head>
<title>Coolify</title>
{#if !$appSession.whiteLabeled} {#if !$appSession.whiteLabeled}
<title>Coolify</title>
<link rel="icon" href="/favicon.png" /> <link rel="icon" href="/favicon.png" />
{:else if $appSession.whiteLabeledDetails.icon} {:else if $appSession.whiteLabeledDetails.icon}
<title>Coolify</title>
<link rel="icon" href={$appSession.whiteLabeledDetails.icon} /> <link rel="icon" href={$appSession.whiteLabeledDetails.icon} />
{/if} {/if}
</svelte:head> </svelte:head>
@@ -120,31 +121,206 @@
<PageLoader /> <PageLoader />
</div> </div>
{/if} {/if}
{#if $appSession.userId} <div class="drawer">
<nav class="nav-main"> <input id="main-drawer" type="checkbox" class="drawer-toggle" />
<div class="flex h-screen w-full flex-col items-center transition-all duration-100"> <div class="drawer-content">
{#if !$appSession.whiteLabeled} {#if $appSession.userId}
<div class="mb-2 mt-4 h-10 w-10"> <nav class="nav-main hidden lg:block z-20">
<img src="/favicon.png" alt="coolLabs logo" /> <div class="flex h-screen w-full flex-col items-center transition-all duration-100">
</div> {#if !$appSession.whiteLabeled}
{:else if $appSession.whiteLabeledDetails.icon} <div class="mb-2 mt-4 h-10 w-10">
<div class="mb-2 mt-4 h-10 w-10"> <img src="/favicon.png" alt="coolLabs logo" />
<img src={$appSession.whiteLabeledDetails.icon} alt="White labeled logo" /> </div>
{:else if $appSession.whiteLabeledDetails.icon}
<div class="mb-2 mt-4 h-10 w-10">
<img src={$appSession.whiteLabeledDetails.icon} alt="White labeled logo" />
</div>
{/if}
<div class="flex flex-col space-y-2 py-2" class:mt-2={$appSession.whiteLabeled}>
<a
id="dashboard"
sveltekit:prefetch
href="/"
class="icons hover:text-white"
class:text-white={$page.url.pathname === '/'}
class:bg-coolgray-500={$page.url.pathname === '/'}
class:bg-coolgray-200={!($page.url.pathname === '/')}
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-9 w-9"
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="M19 8.71l-5.333 -4.148a2.666 2.666 0 0 0 -3.274 0l-5.334 4.148a2.665 2.665 0 0 0 -1.029 2.105v7.2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-7.2c0 -.823 -.38 -1.6 -1.03 -2.105"
/>
<path d="M16 15c-2.21 1.333 -5.792 1.333 -8 0" />
</svg>
</a>
{#if $appSession.teamId === '0'}
<a
id="servers"
sveltekit:prefetch
href="/servers"
class="icons hover:text-white"
class:text-white={$page.url.pathname === '/servers'}
class:bg-coolgray-500={$page.url.pathname === '/servers'}
class:bg-coolgray-200={!($page.url.pathname === '/servers')}
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-8 h-8 mx-auto"
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" />
<rect x="3" y="4" width="18" height="8" rx="3" />
<rect x="3" y="12" width="18" height="8" rx="3" />
<line x1="7" y1="8" x2="7" y2="8.01" />
<line x1="7" y1="16" x2="7" y2="16.01" />
</svg>
</a>
{/if}
</div>
<Tooltip triggeredBy="#dashboard" placement="right">Dashboard</Tooltip>
<Tooltip triggeredBy="#servers" placement="right">Servers</Tooltip>
<div class="flex-1" />
<UpdateAvailable />
<div class="flex flex-col space-y-2 py-2">
<a
id="iam"
sveltekit:prefetch
href="/iam"
class="icons bg-coolgray-200"
class:text-iam={$page.url.pathname.startsWith('/iam')}
class:bg-coolgray-500={$page.url.pathname.startsWith('/iam')}
><svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
class="h-9 w-9"
stroke-width="1.5"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<circle cx="9" cy="7" r="4" />
<path d="M3 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2" />
<path d="M16 3.13a4 4 0 0 1 0 7.75" />
<path d="M21 21v-2a4 4 0 0 0 -3 -3.85" />
</svg>
</a>
<a
id="settings"
sveltekit:prefetch
href={$appSession.teamId === '0' ? '/settings/global' : '/settings/ssh-keys'}
class="icons bg-coolgray-200"
class:text-settings={$page.url.pathname.startsWith('/settings')}
class:bg-coolgray-500={$page.url.pathname.startsWith('/settings')}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
class="h-9 w-9"
stroke-width="1.5"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path
d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z"
/>
<circle cx="12" cy="12" r="3" />
</svg>
</a>
<div id="logout" class="icons bg-coolgray-200 hover:text-error" on:click={logout}>
<svg
xmlns="http://www.w3.org/2000/svg"
class="ml-1 h-8 w-8"
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="M14 8v-2a2 2 0 0 0 -2 -2h-7a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h7a2 2 0 0 0 2 -2v-2"
/>
<path d="M7 12h14l-3 -3m0 6l3 -3" />
</svg>
</div>
<div
class="w-full text-center font-bold text-stone-400 hover:bg-coolgray-200 hover:text-white"
>
<a
class="text-[10px] no-underline"
href={`https://github.com/coollabsio/coolify/releases/tag/v${$appSession.version}`}
target="_blank">v{$appSession.version}</a
>
</div>
</div>
</div> </div>
</nav>
{#if $appSession.whiteLabeled}
<span class="fixed bottom-0 left-[50px] z-50 m-2 px-4 text-xs text-stone-700"
>Powered by <a href="https://coolify.io" target="_blank">Coolify</a></span
>
{/if} {/if}
<div class="flex flex-col space-y-2 py-2" class:mt-2={$appSession.whiteLabeled}> {/if}
<div
class="navbar lg:hidden space-x-2 flex flex-row items-center bg-coollabs"
class:hidden={!$appSession.userId}
>
<label for="main-drawer" class="drawer-button btn btn-square btn-ghost flex-col">
<span class="burger bg-white" />
<span class="burger bg-white" />
<span class="burger bg-white" />
</label>
<div class="prose flex flex-row justify-between space-x-1 w-full items-center pr-3">
{#if !$appSession.whiteLabeled}
<h3 class="mb-0 text-white">Coolify</h3>
{/if}
<UpdateAvailable />
</div>
</div>
<main>
<div class={$appSession.userId ? 'lg:pl-16' : null}>
<slot />
</div>
</main>
</div>
<div class="drawer-side">
<label for="main-drawer" class="drawer-overlay w-full" />
<ul class="menu bg-coolgray-300 w-60 p-2 space-y-3 pt-4 ">
<li>
<a <a
id="dashboard" class="no-underline icons hover:text-white"
sveltekit:prefetch sveltekit:prefetch
href="/" href="/"
class="icons hover:text-white"
class:text-pink-500={$page.url.pathname === '/'} class:text-pink-500={$page.url.pathname === '/'}
class:bg-coolgray-500={$page.url.pathname === '/'} class:bg-coolgray-500={$page.url.pathname === '/'}
class:bg-coolgray-200={!($page.url.pathname === '/')} class:bg-coolgray-200={!($page.url.pathname === '/')}
> >
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
class="h-9 w-9" class="h-8 w-8"
viewBox="0 0 24 24" viewBox="0 0 24 24"
stroke-width="1.5" stroke-width="1.5"
stroke="currentColor" stroke="currentColor"
@@ -158,54 +334,42 @@
/> />
<path d="M16 15c-2.21 1.333 -5.792 1.333 -8 0" /> <path d="M16 15c-2.21 1.333 -5.792 1.333 -8 0" />
</svg> </svg>
Dashboard
</a> </a>
{#if $appSession.teamId === '0'} </li>
<a
id="servers"
sveltekit:prefetch
href="/servers"
class="icons hover:text-white"
class:text-sky-500={$page.url.pathname === '/servers'}
class:bg-coolgray-500={$page.url.pathname === '/servers'}
class:bg-coolgray-200={!($page.url.pathname === '/servers')}
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-8 h-8 mx-auto"
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" />
<rect x="3" y="4" width="18" height="8" rx="3" />
<rect x="3" y="12" width="18" height="8" rx="3" />
<line x1="7" y1="8" x2="7" y2="8.01" />
<line x1="7" y1="16" x2="7" y2="16.01" />
</svg>
</a>
{/if}
</div>
<Tooltip triggeredBy="#dashboard" placement="right">Dashboard</Tooltip>
<Tooltip triggeredBy="#servers" placement="right">Servers</Tooltip>
<div class="flex-1" />
<UpdateAvailable /> <li>
<div class="flex flex-col space-y-2 py-2">
<a <a
id="iam" class="no-underline icons hover:text-white"
sveltekit:prefetch sveltekit:prefetch
href="/iam" href="/servers"
class="icons bg-coolgray-200" class:bg-applications={$page.url.pathname.startsWith('/servers')}
class:text-iam={$page.url.pathname.startsWith('/iam')} >
class:bg-coolgray-500={$page.url.pathname === '/iam'} <svg
class:bg-coolgray-200={!($page.url.pathname === '/iam')} xmlns="http://www.w3.org/2000/svg"
class="w-8 h-8"
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" />
<rect x="3" y="4" width="18" height="8" rx="3" />
<rect x="3" y="12" width="18" height="8" rx="3" />
<line x1="7" y1="8" x2="7" y2="8.01" />
<line x1="7" y1="16" x2="7" y2="16.01" />
</svg>
Servers
</a>
</li>
<li>
<a class="no-underline icons hover:text-white" href="/iam" class:bg-iam={$page.url.pathname.startsWith('/iam')}
><svg ><svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
class="h-9 w-9" class="h-8 w-8"
stroke-width="1.5" stroke-width="1.5"
stroke="currentColor" stroke="currentColor"
fill="none" fill="none"
@@ -218,22 +382,21 @@
<path d="M16 3.13a4 4 0 0 1 0 7.75" /> <path d="M16 3.13a4 4 0 0 1 0 7.75" />
<path d="M21 21v-2a4 4 0 0 0 -3 -3.85" /> <path d="M21 21v-2a4 4 0 0 0 -3 -3.85" />
</svg> </svg>
IAM
</a> </a>
<Tooltip triggeredBy="#iam" placement="right" color="bg-iam">IAM</Tooltip> <Tooltip triggeredBy="#iam" placement="right" color="bg-iam">IAM</Tooltip>
</li>
<li>
<a <a
id="settings" class="no-underline icons hover:text-white"
sveltekit:prefetch
href={$appSession.teamId === '0' ? '/settings/global' : '/settings/ssh-keys'} href={$appSession.teamId === '0' ? '/settings/global' : '/settings/ssh-keys'}
class="icons bg-coolgray-200" class:bg-settings={$page.url.pathname.startsWith('/settings')}
class:text-settings={$page.url.pathname.startsWith('/settings')} class:text-black={$page.url.pathname.startsWith('/settings')}
class:bg-coolgray-500={$page.url.pathname === '/settings'}
class:bg-coolgray-200={!($page.url.pathname === '/settings')}
> >
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
class="h-9 w-9" class="h-8 w-8"
stroke-width="1.5" stroke-width="1.5"
stroke="currentColor" stroke="currentColor"
fill="none" fill="none"
@@ -246,12 +409,14 @@
/> />
<circle cx="12" cy="12" r="3" /> <circle cx="12" cy="12" r="3" />
</svg> </svg>
Settings
</a> </a>
<Tooltip triggeredBy="#settings" placement="right" color="bg-settings text-black" <Tooltip triggeredBy="#settings" placement="right" color="bg-settings text-black"
>Settings</Tooltip >Settings</Tooltip
> >
</li>
<div id="logout" class="icons bg-coolgray-200 hover:text-error" on:click={logout}> <li>
<div class="no-underline icons hover:bg-error" on:click={logout}>
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
class="ml-1 h-8 w-8" class="ml-1 h-8 w-8"
@@ -268,29 +433,18 @@
/> />
<path d="M7 12h14l-3 -3m0 6l3 -3" /> <path d="M7 12h14l-3 -3m0 6l3 -3" />
</svg> </svg>
<div class="-ml-1">Logout</div>
</div> </div>
<Tooltip triggeredBy="#logout" placement="right" color="bg-red-600">Logout</Tooltip> <Tooltip triggeredBy="#logout" placement="right" color="bg-red-600">Logout</Tooltip>
</li>
<div <li class="flex-1 bg-transparent" />
class="w-full text-center font-bold text-stone-400 hover:bg-coolgray-200 hover:text-white" <li class="w-full justify-center">
<a
class="text-xs hover:bg-coolgray-200 no-underline hover:text-white"
href={`https://github.com/coollabsio/coolify/releases/tag/v${$appSession.version}`}
target="_blank">Changelog: v{$appSession.version}</a
> >
<a </li>
class="text-[10px] no-underline" </ul>
href={`https://github.com/coollabsio/coolify/releases/tag/v${$appSession.version}`}
target="_blank">v{$appSession.version}</a
>
</div>
</div>
</div>
</nav>
{#if $appSession.whiteLabeled}
<span class="fixed bottom-0 left-[50px] z-50 m-2 px-4 text-xs text-stone-700"
>Powered by <a href="https://coolify.io" target="_blank">Coolify</a></span
>
{/if}
{/if}
<main>
<div class={$appSession.userId ? 'pl-14 lg:pl-20' : null}>
<slot />
</div> </div>
</main> </div>

View File

@@ -100,6 +100,7 @@
<td> <td>
<input <input
style="min-width: 350px !important;"
id={isNewSecret ? 'secretName' : 'secretNameNew'} id={isNewSecret ? 'secretName' : 'secretNameNew'}
bind:value={name} bind:value={name}
required required
@@ -116,6 +117,7 @@
isPasswordField={true} isPasswordField={true}
bind:value bind:value
placeholder="J$#@UIO%HO#$U%H" placeholder="J$#@UIO%HO#$U%H"
inputStyle="min-width: 350px; !important"
/> />
</td> </td>
<td class="text-center"> <td class="text-center">

View File

@@ -188,163 +188,296 @@
}); });
</script> </script>
<nav class="nav-side"> <nav class="header lg:flex-row flex-col-reverse">
{#if $location} <div class="flex flex-row space-x-2 font-bold pt-10 lg:pt-0">
<a <div class="flex flex-col items-center justify-center">
id="open" <div class="title">
href={$location} {#if $page.url.pathname === `/applications/${id}`}
target="_blank" Configurations
class="icons flex items-center bg-transparent text-sm" {:else if $page.url.pathname === `/applications/${id}/secrets`}
><svg Secrets
xmlns="http://www.w3.org/2000/svg" {:else if $page.url.pathname === `/applications/${id}/storages`}
class="h-6 w-6" Persistent Storages
viewBox="0 0 24 24" {:else if $page.url.pathname === `/applications/${id}/previews`}
stroke-width="1.5" Preview Deployments
stroke="currentColor" {:else if $page.url.pathname === `/applications/${id}/logs`}
fill="none" Application Logs
stroke-linecap="round" {:else if $page.url.pathname === `/applications/${id}/logs/build`}
stroke-linejoin="round" Build Logs
{:else if $page.url.pathname === `/applications/${id}/configuration/source`}
Select a Git Source
{:else if $page.url.pathname === `/applications/${id}/configuration/destination`}
Select a Destination
{:else if $page.url.pathname === `/applications/${id}/configuration/buildpack`}
Select a Build Pack
{/if}
</div>
</div>
{#if application.gitSource?.htmlUrl && application.repository && application.branch}
<a
id="git"
href="{application.gitSource.htmlUrl}/{application.repository}/tree/{application.branch}"
target="_blank"
class="w-10"
> >
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> {#if application.gitSource?.type === 'gitlab'}
<path d="M11 7h-5a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-5" /> <svg viewBox="0 0 128 128" class="icons">
<line x1="10" y1="14" x2="20" y2="4" /> <path
<polyline points="15 4 20 4 20 9" /> fill="#FC6D26"
</svg></a d="M126.615 72.31l-7.034-21.647L105.64 7.76c-.716-2.206-3.84-2.206-4.556 0l-13.94 42.903H40.856L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664 1.385 72.31a4.792 4.792 0 001.74 5.358L64 121.894l60.874-44.227a4.793 4.793 0 001.74-5.357"
> /><path fill="#E24329" d="M64 121.894l23.144-71.23H40.856L64 121.893z" /><path
<Tooltip triggeredBy="#open">Open</Tooltip> fill="#FC6D26"
d="M64 121.894l-23.144-71.23H8.42L64 121.893z"
/><path
fill="#FCA326"
d="M8.42 50.663L1.384 72.31a4.79 4.79 0 001.74 5.357L64 121.894 8.42 50.664z"
/><path
fill="#E24329"
d="M8.42 50.663h32.436L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664z"
/><path fill="#FC6D26" d="M64 121.894l23.144-71.23h32.437L64 121.893z" /><path
fill="#FCA326"
d="M119.58 50.663l7.035 21.647a4.79 4.79 0 01-1.74 5.357L64 121.894l55.58-71.23z"
/><path
fill="#E24329"
d="M119.58 50.663H87.145l13.94-42.902c.717-2.206 3.84-2.206 4.557 0l13.94 42.903z"
/>
</svg>
{:else if application.gitSource?.type === 'github'}
<svg viewBox="0 0 128 128" class="icons">
<g fill="#ffffff"
><path
fill-rule="evenodd"
clip-rule="evenodd"
d="M64 5.103c-33.347 0-60.388 27.035-60.388 60.388 0 26.682 17.303 49.317 41.297 57.303 3.017.56 4.125-1.31 4.125-2.905 0-1.44-.056-6.197-.082-11.243-16.8 3.653-20.345-7.125-20.345-7.125-2.747-6.98-6.705-8.836-6.705-8.836-5.48-3.748.413-3.67.413-3.67 6.063.425 9.257 6.223 9.257 6.223 5.386 9.23 14.127 6.562 17.573 5.02.542-3.903 2.107-6.568 3.834-8.076-13.413-1.525-27.514-6.704-27.514-29.843 0-6.593 2.36-11.98 6.223-16.21-.628-1.52-2.695-7.662.584-15.98 0 0 5.07-1.623 16.61 6.19C53.7 35 58.867 34.327 64 34.304c5.13.023 10.3.694 15.127 2.033 11.526-7.813 16.59-6.19 16.59-6.19 3.287 8.317 1.22 14.46.593 15.98 3.872 4.23 6.215 9.617 6.215 16.21 0 23.194-14.127 28.3-27.574 29.796 2.167 1.874 4.097 5.55 4.097 11.183 0 8.08-.07 14.583-.07 16.572 0 1.607 1.088 3.49 4.148 2.897 23.98-7.994 41.263-30.622 41.263-57.294C124.388 32.14 97.35 5.104 64 5.104z"
/><path
d="M26.484 91.806c-.133.3-.605.39-1.035.185-.44-.196-.685-.605-.543-.906.13-.31.603-.395 1.04-.188.44.197.69.61.537.91zm2.446 2.729c-.287.267-.85.143-1.232-.28-.396-.42-.47-.983-.177-1.254.298-.266.844-.14 1.24.28.394.426.472.984.17 1.255zM31.312 98.012c-.37.258-.976.017-1.35-.52-.37-.538-.37-1.183.01-1.44.373-.258.97-.025 1.35.507.368.545.368 1.19-.01 1.452zm3.261 3.361c-.33.365-1.036.267-1.552-.23-.527-.487-.674-1.18-.343-1.544.336-.366 1.045-.264 1.564.23.527.486.686 1.18.333 1.543zm4.5 1.951c-.147.473-.825.688-1.51.486-.683-.207-1.13-.76-.99-1.238.14-.477.823-.7 1.512-.485.683.206 1.13.756.988 1.237zm4.943.361c.017.498-.563.91-1.28.92-.723.017-1.308-.387-1.315-.877 0-.503.568-.91 1.29-.924.717-.013 1.306.387 1.306.88zm4.598-.782c.086.485-.413.984-1.126 1.117-.7.13-1.35-.172-1.44-.653-.086-.498.422-.997 1.122-1.126.714-.123 1.354.17 1.444.663zm0 0"
/></g
>
</svg>
{/if}
</a>
<Tooltip triggeredBy="#git">Open on Git</Tooltip>
{/if}
</div>
<div class="lg:block hidden flex-1" />
<div class="flex flex-row flex-wrap space-x-3 justify-center lg:justify-start lg:py-0">
{#if $location}
<a id="open" href={$location} target="_blank" class="icons bg-transparent"
><svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-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="M11 7h-5a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-5" />
<line x1="10" y1="14" x2="20" y2="4" />
<polyline points="15 4 20 4 20 9" />
</svg></a
>
<Tooltip triggeredBy="#open">Open</Tooltip>
<div class="border border-coolgray-500 h-8" /> <div class="hidden lg:block border border-coolgray-500 h-8" />
{/if} {/if}
{#if $status.application.isExited || $status.application.isRestarting}
{#if $status.application.isExited || $status.application.isRestarting} <a
<a id="applicationerror"
id="applicationerror" href={$isDeploymentEnabled ? `/applications/${id}/logs` : null}
href={$isDeploymentEnabled ? `/applications/${id}/logs` : null} class="icons bg-transparent text-sm text-error"
class="icons bg-transparent text-sm flex items-center text-error" sveltekit:prefetch
sveltekit:prefetch
>
<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"
> >
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> <svg
<path xmlns="http://www.w3.org/2000/svg"
d="M8.7 3h6.6c.3 0 .5 .1 .7 .3l4.7 4.7c.2 .2 .3 .4 .3 .7v6.6c0 .3 -.1 .5 -.3 .7l-4.7 4.7c-.2 .2 -.4 .3 -.7 .3h-6.6c-.3 0 -.5 -.1 -.7 -.3l-4.7 -4.7c-.2 -.2 -.3 -.4 -.3 -.7v-6.6c0 -.3 .1 -.5 .3 -.7l4.7 -4.7c.2 -.2 .4 -.3 .7 -.3z" class="w-6 h-6"
/> viewBox="0 0 24 24"
<line x1="12" y1="8" x2="12" y2="12" /> stroke-width="1.5"
<line x1="12" y1="16" x2="12.01" y2="16" /> stroke="currentcolor"
</svg> fill="none"
</a> stroke-linecap="round"
<Tooltip triggeredBy="#applicationerror">Application exited or restarting!</Tooltip> stroke-linejoin="round"
<button >
id="stop" <path stroke="none" d="M0 0h24v24H0z" fill="none" />
on:click={stopApplication} <path
type="submit" d="M8.7 3h6.6c.3 0 .5 .1 .7 .3l4.7 4.7c.2 .2 .3 .4 .3 .7v6.6c0 .3 -.1 .5 -.3 .7l-4.7 4.7c-.2 .2 -.4 .3 -.7 .3h-6.6c-.3 0 -.5 -.1 -.7 -.3l-4.7 -4.7c-.2 -.2 -.3 -.4 -.3 -.7v-6.6c0 -.3 .1 -.5 .3 -.7l4.7 -4.7c.2 -.2 .4 -.3 .7 -.3z"
disabled={!$isDeploymentEnabled} />
class="icons bg-transparent text-sm flex items-center space-x-2 text-error" <line x1="12" y1="8" x2="12" y2="12" />
> <line x1="12" y1="16" x2="12.01" y2="16" />
<svg </svg>
xmlns="http://www.w3.org/2000/svg" </a>
class="w-6 h-6" <Tooltip triggeredBy="#applicationerror">Application exited with an error!</Tooltip>
viewBox="0 0 24 24" {/if}
stroke-width="1.5" {#if $status.application.initialLoading}
stroke="currentColor" <button class="icons animate-spin bg-transparent duration-500 ease-in-out">
fill="none" <svg
stroke-linecap="round" xmlns="http://www.w3.org/2000/svg"
stroke-linejoin="round" class="h-6 w-6"
> viewBox="0 0 24 24"
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> stroke-width="1.5"
<rect x="6" y="5" width="4" height="14" rx="1" /> stroke="currentColor"
<rect x="14" y="5" width="4" height="14" rx="1" /> fill="none"
</svg> stroke-linecap="round"
</button> stroke-linejoin="round"
<Tooltip triggeredBy="#stop">Stop</Tooltip> >
{/if} <path stroke="none" d="M0 0h24v24H0z" fill="none" />
{#if $status.application.initialLoading} <path d="M9 4.55a8 8 0 0 1 6 14.9m0 -4.45v5h5" />
<button <line x1="5.63" y1="7.16" x2="5.63" y2="7.17" />
class="icons flex animate-spin items-center space-x-2 bg-transparent text-sm duration-500 ease-in-out hover:bg-transparent" <line x1="4.06" y1="11" x2="4.06" y2="11.01" />
> <line x1="4.63" y1="15.1" x2="4.63" y2="15.11" />
<svg <line x1="7.16" y1="18.37" x2="7.16" y2="18.38" />
xmlns="http://www.w3.org/2000/svg" <line x1="11" y1="19.94" x2="11" y2="19.95" />
class="h-6 w-6" </svg>
viewBox="0 0 24 24" </button>
stroke-width="1.5" {:else if $status.application.isRunning}
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M9 4.55a8 8 0 0 1 6 14.9m0 -4.45v5h5" />
<line x1="5.63" y1="7.16" x2="5.63" y2="7.17" />
<line x1="4.06" y1="11" x2="4.06" y2="11.01" />
<line x1="4.63" y1="15.1" x2="4.63" y2="15.11" />
<line x1="7.16" y1="18.37" x2="7.16" y2="18.38" />
<line x1="11" y1="19.94" x2="11" y2="19.95" />
</svg>
</button>
{:else if $status.application.isRunning}
<button
id="stop"
on:click={stopApplication}
type="submit"
disabled={!$isDeploymentEnabled}
class="icons bg-transparent text-sm flex items-center space-x-2 text-error"
>
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<rect x="6" y="5" width="4" height="14" rx="1" />
<rect x="14" y="5" width="4" height="14" rx="1" />
</svg>
</button>
<Tooltip triggeredBy="#stop">Stop</Tooltip>
<button
id="restart"
on:click={restartApplication}
type="submit"
disabled={!$isDeploymentEnabled}
class="icons bg-transparent text-sm flex items-center space-x-2"
>
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4" />
<path d="M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4" />
</svg>
</button>
<Tooltip triggeredBy="#restart">Restart (useful to change secrets)</Tooltip>
<form on:submit|preventDefault={() => handleDeploySubmit(true)}>
<button <button
id="forceredeploy" id="stop"
on:click={stopApplication}
type="submit" type="submit"
disabled={!$isDeploymentEnabled} disabled={!$isDeploymentEnabled}
class="icons bg-transparent text-sm flex items-center space-x-2" class="icons bg-transparent text-error"
> >
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<rect x="6" y="5" width="4" height="14" rx="1" />
<rect x="14" y="5" width="4" height="14" rx="1" />
</svg>
</button>
<Tooltip triggeredBy="#stop">Stop</Tooltip>
<button
id="restart"
on:click={restartApplication}
type="submit"
disabled={!$isDeploymentEnabled}
class="icons bg-transparent"
>
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M20 11a8.1 8.1 0 0 0 -15.5 -2m-.5 -4v4h4" />
<path d="M4 13a8.1 8.1 0 0 0 15.5 2m.5 4v-4h-4" />
</svg>
</button>
<Tooltip triggeredBy="#restart">Restart (useful to change secrets)</Tooltip>
<form on:submit|preventDefault={() => handleDeploySubmit(true)}>
<button
id="forceredeploy"
type="submit"
disabled={!$isDeploymentEnabled}
class="icons bg-transparent"
>
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path
d="M16.3 5h.7a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2h5l-2.82 -2.82m0 5.64l2.82 -2.82"
transform="rotate(-45 12 12)"
/>
</svg>
</button>
<Tooltip triggeredBy="#forceredeploy">Force redeploy (without cache)</Tooltip>
</form>
{:else}
<form on:submit|preventDefault={() => handleDeploySubmit(false)}>
<button
id="deploy"
type="submit"
disabled={!$isDeploymentEnabled}
class="icons bg-transparent text-success"
>
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M7 4v16l13 -8z" />
</svg>
</button>
<Tooltip triggeredBy="#deploy">Deploy</Tooltip>
</form>
{/if}
<div class="hidden lg:block border border-coolgray-500 h-8" />
<a
href={$isDeploymentEnabled ? `/applications/${id}` : null}
sveltekit:prefetch
class="hover:text-yellow-500 rounded"
class:text-yellow-500={$page.url.pathname === `/applications/${id}`}
class:bg-coolgray-500={$page.url.pathname === `/applications/${id}`}
>
<button
disabled={!$isDeploymentEnabled}
id="configurations"
class="icons bg-transparent text-sm"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-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" />
<rect x="4" y="8" width="4" height="4" />
<line x1="6" y1="4" x2="6" y2="8" />
<line x1="6" y1="12" x2="6" y2="20" />
<rect x="10" y="14" width="4" height="4" />
<line x1="12" y1="4" x2="12" y2="14" />
<line x1="12" y1="18" x2="12" y2="20" />
<rect x="16" y="5" width="4" height="4" />
<line x1="18" y1="4" x2="18" y2="5" />
<line x1="18" y1="9" x2="18" y2="20" />
</svg></button
></a
>
<Tooltip triggeredBy="#configurations">Configurations</Tooltip>
<a
href={$isDeploymentEnabled ? `/applications/${id}/secrets` : null}
sveltekit:prefetch
class="hover:text-pink-500 rounded"
class:text-pink-500={$page.url.pathname === `/applications/${id}/secrets`}
class:bg-coolgray-500={$page.url.pathname === `/applications/${id}/secrets`}
>
<button id="secrets" disabled={!$isDeploymentEnabled} class="icons bg-transparent text-sm">
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6" class="w-6 h-6"
@@ -357,256 +490,168 @@
> >
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path <path
d="M16.3 5h.7a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2h5l-2.82 -2.82m0 5.64l2.82 -2.82" d="M12 3a12 12 0 0 0 8.5 3a12 12 0 0 1 -8.5 15a12 12 0 0 1 -8.5 -15a12 12 0 0 0 8.5 -3"
transform="rotate(-45 12 12)"
/> />
</svg> <circle cx="12" cy="11" r="1" />
</button> <line x1="12" y1="12" x2="12" y2="14.5" />
<Tooltip triggeredBy="#forceredeploy">Force redeploy (without cache)</Tooltip>
</form>
{:else}
<form on:submit|preventDefault={() => handleDeploySubmit(false)}>
<button
id="deploy"
type="submit"
disabled={!$isDeploymentEnabled}
class="icons bg-transparent text-sm flex items-center space-x-2 text-success"
>
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M7 4v16l13 -8z" />
</svg>
</button>
<Tooltip triggeredBy="#deploy">Deploy</Tooltip>
</form>
{/if}
<div class="border border-coolgray-500 h-8" />
<a
href={$isDeploymentEnabled ? `/applications/${id}` : null}
sveltekit:prefetch
class="hover:text-yellow-500 rounded"
class:text-yellow-500={$page.url.pathname === `/applications/${id}`}
class:bg-coolgray-500={$page.url.pathname === `/applications/${id}`}
>
<button
disabled={!$isDeploymentEnabled}
id="configurations"
class="icons bg-transparent text-sm"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-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" />
<rect x="4" y="8" width="4" height="4" />
<line x1="6" y1="4" x2="6" y2="8" />
<line x1="6" y1="12" x2="6" y2="20" />
<rect x="10" y="14" width="4" height="4" />
<line x1="12" y1="4" x2="12" y2="14" />
<line x1="12" y1="18" x2="12" y2="20" />
<rect x="16" y="5" width="4" height="4" />
<line x1="18" y1="4" x2="18" y2="5" />
<line x1="18" y1="9" x2="18" y2="20" />
</svg></button
></a
>
<Tooltip triggeredBy="#configurations">Configurations</Tooltip>
<a
href={$isDeploymentEnabled ? `/applications/${id}/secrets` : null}
sveltekit:prefetch
class="hover:text-pink-500 rounded"
class:text-pink-500={$page.url.pathname === `/applications/${id}/secrets`}
class:bg-coolgray-500={$page.url.pathname === `/applications/${id}/secrets`}
>
<button id="secrets" disabled={!$isDeploymentEnabled} class="icons bg-transparent text-sm">
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path
d="M12 3a12 12 0 0 0 8.5 3a12 12 0 0 1 -8.5 15a12 12 0 0 1 -8.5 -15a12 12 0 0 0 8.5 -3"
/>
<circle cx="12" cy="11" r="1" />
<line x1="12" y1="12" x2="12" y2="14.5" />
</svg></button
></a
>
<Tooltip triggeredBy="#secrets">Secrets</Tooltip>
<a
href={$isDeploymentEnabled ? `/applications/${id}/storages` : null}
sveltekit:prefetch
class="hover:text-pink-500 rounded"
class:text-pink-500={$page.url.pathname === `/applications/${id}/storages`}
class:bg-coolgray-500={$page.url.pathname === `/applications/${id}/storages`}
>
<button
id="persistentstorages"
disabled={!$isDeploymentEnabled}
class="icons bg-transparent text-sm"
>
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<ellipse cx="12" cy="6" rx="8" ry="3" />
<path d="M4 6v6a8 3 0 0 0 16 0v-6" />
<path d="M4 12v6a8 3 0 0 0 16 0v-6" />
</svg>
</button></a
>
<Tooltip triggeredBy="#persistentstorages">Persistent Storages</Tooltip>
{#if !application.settings.isBot}
<a
href={$isDeploymentEnabled ? `/applications/${id}/previews` : null}
sveltekit:prefetch
class="hover:text-orange-500 rounded"
class:text-orange-500={$page.url.pathname === `/applications/${id}/previews`}
class:bg-coolgray-500={$page.url.pathname === `/applications/${id}/previews`}
>
<button id="previews" disabled={!$isDeploymentEnabled} class="icons bg-transparent text-sm">
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<circle cx="7" cy="18" r="2" />
<circle cx="7" cy="6" r="2" />
<circle cx="17" cy="12" r="2" />
<line x1="7" y1="8" x2="7" y2="16" />
<path d="M7 8a4 4 0 0 0 4 4h4" />
</svg></button </svg></button
></a ></a
> >
<Tooltip triggeredBy="#previews">Previews</Tooltip> <Tooltip triggeredBy="#secrets">Secrets</Tooltip>
{/if} <a
<div class="border border-coolgray-500 h-8" /> href={$isDeploymentEnabled ? `/applications/${id}/storages` : null}
<a sveltekit:prefetch
href={$isDeploymentEnabled && $status.application.isRunning ? `/applications/${id}/logs` : null} class="hover:text-pink-500 rounded"
sveltekit:prefetch class:text-pink-500={$page.url.pathname === `/applications/${id}/storages`}
class="hover:text-sky-500 rounded" class:bg-coolgray-500={$page.url.pathname === `/applications/${id}/storages`}
class:text-sky-500={$page.url.pathname === `/applications/${id}/logs`}
class:bg-coolgray-500={$page.url.pathname === `/applications/${id}/logs`}
>
<button
id="applicationlogs"
disabled={!$isDeploymentEnabled || !$status.application.isRunning}
class="icons bg-transparent text-sm"
> >
<svg <button
xmlns="http://www.w3.org/2000/svg" id="persistentstorages"
class="h-6 w-6" disabled={!$isDeploymentEnabled}
viewBox="0 0 24 24" class="icons bg-transparent text-sm"
stroke-width="1.5"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
> >
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> <svg
<path d="M3 19a9 9 0 0 1 9 0a9 9 0 0 1 9 0" /> xmlns="http://www.w3.org/2000/svg"
<path d="M3 6a9 9 0 0 1 9 0a9 9 0 0 1 9 0" /> class="w-6 h-6"
<line x1="3" y1="6" x2="3" y2="19" /> viewBox="0 0 24 24"
<line x1="12" y1="6" x2="12" y2="19" /> stroke-width="1.5"
<line x1="21" y1="6" x2="21" y2="19" /> stroke="currentColor"
</svg> fill="none"
</button></a stroke-linecap="round"
> stroke-linejoin="round"
<Tooltip triggeredBy="#applicationlogs">Application Logs</Tooltip> >
<a <path stroke="none" d="M0 0h24v24H0z" fill="none" />
href={$isDeploymentEnabled ? `/applications/${id}/logs/build` : null} <ellipse cx="12" cy="6" rx="8" ry="3" />
sveltekit:prefetch <path d="M4 6v6a8 3 0 0 0 16 0v-6" />
class="hover:text-red-500 rounded" <path d="M4 12v6a8 3 0 0 0 16 0v-6" />
class:text-red-500={$page.url.pathname === `/applications/${id}/logs/build`} </svg>
class:bg-coolgray-500={$page.url.pathname === `/applications/${id}/logs/build`} </button></a
> >
<button id="buildlogs" disabled={!$isDeploymentEnabled} class="icons bg-transparent text-sm"> <Tooltip triggeredBy="#persistentstorages">Persistent Storages</Tooltip>
<svg {#if !application.settings.isBot}
xmlns="http://www.w3.org/2000/svg" <a
class="h-6 w-6" href={$isDeploymentEnabled ? `/applications/${id}/previews` : null}
viewBox="0 0 24 24" sveltekit:prefetch
stroke-width="1.5" class="hover:text-orange-500 rounded"
stroke="currentColor" class:text-orange-500={$page.url.pathname === `/applications/${id}/previews`}
fill="none" class:bg-coolgray-500={$page.url.pathname === `/applications/${id}/previews`}
stroke-linecap="round"
stroke-linejoin="round"
> >
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> <button id="previews" disabled={!$isDeploymentEnabled} class="icons bg-transparent text-sm">
<circle cx="19" cy="13" r="2" /> <svg
<circle cx="4" cy="17" r="2" /> xmlns="http://www.w3.org/2000/svg"
<circle cx="13" cy="17" r="2" /> class="w-6 h-6"
<line x1="13" y1="19" x2="4" y2="19" /> viewBox="0 0 24 24"
<line x1="4" y1="15" x2="13" y2="15" /> stroke-width="1.5"
<path d="M8 12v-5h2a3 3 0 0 1 3 3v5" /> stroke="currentColor"
<path d="M5 15v-2a1 1 0 0 1 1 -1h7" /> fill="none"
<path d="M19 11v-7l-6 7" /> stroke-linecap="round"
</svg> stroke-linejoin="round"
</button></a >
> <path stroke="none" d="M0 0h24v24H0z" fill="none" />
<Tooltip triggeredBy="#buildlogs">Build Logs</Tooltip> <circle cx="7" cy="18" r="2" />
<div class="border border-coolgray-500 h-8" /> <circle cx="7" cy="6" r="2" />
<circle cx="17" cy="12" r="2" />
<line x1="7" y1="8" x2="7" y2="16" />
<path d="M7 8a4 4 0 0 0 4 4h4" />
</svg></button
></a
>
<Tooltip triggeredBy="#previews">Previews</Tooltip>
{/if}
<div class="hidden lg:block border border-coolgray-500 h-8" />
<a
href={$isDeploymentEnabled && $status.application.isRunning
? `/applications/${id}/logs`
: null}
sveltekit:prefetch
class="hover:text-sky-500 rounded"
class:text-sky-500={$page.url.pathname === `/applications/${id}/logs`}
class:bg-coolgray-500={$page.url.pathname === `/applications/${id}/logs`}
>
<button
id="applicationlogs"
disabled={!$isDeploymentEnabled || !$status.application.isRunning}
class="icons bg-transparent text-sm"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-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="M3 19a9 9 0 0 1 9 0a9 9 0 0 1 9 0" />
<path d="M3 6a9 9 0 0 1 9 0a9 9 0 0 1 9 0" />
<line x1="3" y1="6" x2="3" y2="19" />
<line x1="12" y1="6" x2="12" y2="19" />
<line x1="21" y1="6" x2="21" y2="19" />
</svg>
</button></a
>
<Tooltip triggeredBy="#applicationlogs">Application Logs</Tooltip>
<a
href={$isDeploymentEnabled ? `/applications/${id}/logs/build` : null}
sveltekit:prefetch
class="hover:text-red-500 rounded"
class:text-red-500={$page.url.pathname === `/applications/${id}/logs/build`}
class:bg-coolgray-500={$page.url.pathname === `/applications/${id}/logs/build`}
>
<button id="buildlogs" disabled={!$isDeploymentEnabled} class="icons bg-transparent text-sm">
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-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" />
<circle cx="19" cy="13" r="2" />
<circle cx="4" cy="17" r="2" />
<circle cx="13" cy="17" r="2" />
<line x1="13" y1="19" x2="4" y2="19" />
<line x1="4" y1="15" x2="13" y2="15" />
<path d="M8 12v-5h2a3 3 0 0 1 3 3v5" />
<path d="M5 15v-2a1 1 0 0 1 1 -1h7" />
<path d="M19 11v-7l-6 7" />
</svg>
</button></a
>
<Tooltip triggeredBy="#buildlogs">Build Logs</Tooltip>
<div class="hidden lg:block border border-coolgray-500 h-8" />
{#if forceDelete} {#if forceDelete}
<button <button
id="forcedelete" id="forcedelete"
on:click={() => deleteApplication(application.name, true)} on:click={() => deleteApplication(application.name, true)}
type="submit" type="submit"
disabled={!$appSession.isAdmin} disabled={!$appSession.isAdmin}
class:bg-red-600={$appSession.isAdmin} class:bg-red-600={$appSession.isAdmin}
class:hover:bg-red-500={$appSession.isAdmin} class:hover:bg-red-500={$appSession.isAdmin}
class="icons bg-transparent text-sm" class="icons bg-transparent text-sm"
> >
Force Delete Force Delete
</button> </button>
<Tooltip triggeredBy="#forcedelete">Force Delete</Tooltip> <Tooltip triggeredBy="#forcedelete" placement="left">Force Delete</Tooltip>
{:else} {:else}
<button <button
id="delete" id="delete"
on:click={() => deleteApplication(application.name, false)} on:click={() => deleteApplication(application.name, false)}
type="submit" type="submit"
disabled={!$appSession.isAdmin} disabled={!$appSession.isAdmin}
class:hover:text-red-500={$appSession.isAdmin} class:hover:text-red-500={$appSession.isAdmin}
class="icons bg-transparent text-sm" class="icons bg-transparent text-sm"
> >
<DeleteIcon /> <DeleteIcon />
</button> </button>
<Tooltip triggeredBy="#delete">Delete</Tooltip> <Tooltip triggeredBy="#delete" placement="left">Delete</Tooltip>
{/if} {/if}
</div>
</nav> </nav>
<slot /> <slot />

View File

@@ -413,7 +413,7 @@
>{loading.save ? $t('forms.saving') : $t('forms.save')}</button >{loading.save ? $t('forms.saving') : $t('forms.save')}</button
> >
{#if tryAgain} {#if tryAgain}
<div> <div class="p-5">
An error occured during authenticating with GitLab. Please check your GitLab Source An error occured during authenticating with GitLab. Please check your GitLab Source
configuration <a href={`/sources/${application.gitSource.id}`}>here.</a> configuration <a href={`/sources/${application.gitSource.id}`}>here.</a>
</div> </div>

View File

@@ -156,40 +156,40 @@
} }
</script> </script>
<div class="mx-auto max-w-5xl"> <div class="mx-auto max-w-6xl">
<div class="grid grid-flow-row gap-2 px-10"> <form
<div class="flex"> class="flex flex-col lg:flex-row w-full lg:px-32 space-y-5 lg:space-y-0 lg:space-x-5 justify-start"
<form class="flex" on:submit|preventDefault={loadBranches}> on:submit|preventDefault={loadBranches}
<div class="space-y-4"> >
<input <div class="space-y-2 w-full">
placeholder="eg: https://github.com/coollabsio/nodejs-example/tree/main" <input
bind:value={publicRepositoryLink} class="w-full"
placeholder="eg: https://github.com/coollabsio/nodejs-example/tree/main"
bind:value={publicRepositoryLink}
/>
{#if branchSelectOptions.length > 0}
<div class="custom-select-wrapper">
<Select
class="w-full"
placeholder={loading.branches
? $t('application.configuration.loading_branches')
: !publicRepositoryLink
? $t('application.configuration.select_a_repository_first')
: $t('application.configuration.select_a_branch')}
isWaiting={loading.branches}
showIndicator={!!publicRepositoryLink && !loading.branches}
id="branches"
on:select={saveRepository}
items={branchSelectOptions}
isDisabled={loading.branches || !!!publicRepositoryLink}
isClearable={false}
/> />
{#if branchSelectOptions.length > 0}
<div class="custom-select-wrapper">
<Select
placeholder={loading.branches
? $t('application.configuration.loading_branches')
: !publicRepositoryLink
? $t('application.configuration.select_a_repository_first')
: $t('application.configuration.select_a_branch')}
isWaiting={loading.branches}
showIndicator={!!publicRepositoryLink && !loading.branches}
id="branches"
on:select={saveRepository}
items={branchSelectOptions}
isDisabled={loading.branches || !!!publicRepositoryLink}
isClearable={false}
/>
</div>
{/if}
</div> </div>
{/if}
<button class="btn mx-4 bg-orange-600" class:loading={loading.branches} type="submit"
>Load Repository</button
>
</form>
</div> </div>
</div>
<button class="btn bg-orange-600" class:loading={loading.branches} type="submit">
Load Repository
</button>
</form>
</div> </div>

View File

@@ -254,12 +254,6 @@
}); });
</script> </script>
<div class="flex space-x-1 p-6 font-bold">
<div class="mr-4 text-2xl tracking-tight">
{$t('application.configuration.configure_build_pack')}
</div>
</div>
{#if scanning} {#if scanning}
<div class="flex justify-center space-x-1 p-6 font-bold"> <div class="flex justify-center space-x-1 p-6 font-bold">
<div class="text-xl tracking-tight"> <div class="text-xl tracking-tight">
@@ -267,18 +261,7 @@
</div> </div>
</div> </div>
{:else} {:else}
<div class="max-w-5xl mx-auto "> <div class="max-w-6xl mx-auto px-5">
<div class="title pb-2">Coolify</div>
<div class="flex flex-wrap justify-center">
{#each buildPacks.filter((bp) => bp.isCoolifyBuildPack === true) as buildPack}
<div class="p-2">
<BuildPack {packageManager} {buildPack} {scanning} bind:foundConfig />
</div>
{/each}
</div>
</div>
<div class="max-w-5xl mx-auto ">
<div class="title pb-2">Other</div> <div class="title pb-2">Other</div>
<div class="flex flex-wrap justify-center"> <div class="flex flex-wrap justify-center">
{#each buildPacks.filter((bp) => bp.isHerokuBuildPack === true) as buildPack} {#each buildPacks.filter((bp) => bp.isHerokuBuildPack === true) as buildPack}
@@ -288,4 +271,14 @@
{/each} {/each}
</div> </div>
</div> </div>
<div class="max-w-6xl mx-auto px-5">
<div class="title pb-2">Coolify Custom</div>
<div class="flex flex-wrap justify-center">
{#each buildPacks.filter((bp) => bp.isCoolifyBuildPack === true) as buildPack}
<div class="p-2">
<BuildPack {packageManager} {buildPack} {scanning} bind:foundConfig />
</div>
{/each}
</div>
</div>
{/if} {/if}

View File

@@ -126,7 +126,7 @@
</div> </div>
{/if} {/if}
<div class="mx-auto max-w-4xl p-6"> <div class="mx-auto max-w-6xl p-6">
<div class="grid grid-flow-row gap-2 px-10"> <div class="grid grid-flow-row gap-2 px-10">
<div class="font-bold text-xl tracking-tight">Connect a Hosted / Remote Database</div> <div class="font-bold text-xl tracking-tight">Connect a Hosted / Remote Database</div>
<div class="mt-2 grid grid-cols-2 items-center px-4"> <div class="mt-2 grid grid-cols-2 items-center px-4">

View File

@@ -63,19 +63,14 @@
}); });
</script> </script>
<div class="flex space-x-1 p-6 font-bold"> <div class="flex flex-col justify-center w-full">
<div class="mr-4 text-2xl tracking-tight">
{$t('application.configuration.configure_destination')}
</div>
</div>
<div class="flex flex-col justify-center">
{#if !destinations || ownDestinations.length === 0} {#if !destinations || ownDestinations.length === 0}
<div class="flex-col"> <div class="flex-col">
<div class="pb-2 text-center font-bold"> <div class="pb-2 text-center font-bold">
{$t('application.configuration.no_configurable_destination')} {$t('application.configuration.no_configurable_destination')}
</div> </div>
<div class="flex justify-center"> <div class="flex justify-center">
<a href="/new/destination" sveltekit:prefetch class="add-icon bg-sky-600 hover:bg-sky-500"> <a href="/destinations/new" sveltekit:prefetch class="add-icon bg-sky-600 hover:bg-sky-500">
<svg <svg
class="w-6" class="w-6"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@@ -93,7 +88,7 @@
</div> </div>
</div> </div>
{:else} {:else}
<div class="flex flex-col flex-wrap justify-center px-2 md:flex-row"> <div class="flex flex-col flex-wrap justify-center px-2 md:flex-row mx-auto">
{#each ownDestinations as destination} {#each ownDestinations as destination}
<div class="p-2"> <div class="p-2">
<form on:submit|preventDefault={() => handleSubmit(destination.id)}> <form on:submit|preventDefault={() => handleSubmit(destination.id)}>
@@ -106,9 +101,9 @@
{/each} {/each}
</div> </div>
{#if otherDestinations.length > 0 && $appSession.teamId === '0'} {#if otherDestinations.length > 0 && $appSession.teamId === '0'}
<div class="px-6 pb-5 pt-10 text-xl font-bold">Other Destinations</div> <div class="px-6 pb-5 pt-10 title">Other Destinations</div>
{/if} {/if}
<div class="flex flex-col flex-wrap justify-center px-2 md:flex-row"> <div class="flex flex-col flex-wrap justify-center px-2 md:flex-row mx-auto">
{#each otherDestinations as destination} {#each otherDestinations as destination}
<div class="p-2"> <div class="p-2">
<form on:submit|preventDefault={() => handleSubmit(destination.id)}> <form on:submit|preventDefault={() => handleSubmit(destination.id)}>

View File

@@ -68,12 +68,7 @@
} }
</script> </script>
<div class="flex space-x-1 p-6 font-bold"> <div class="max-w-6xl mx-auto px-5">
<div class="mr-4 text-2xl tracking-tight">
{$t('application.configuration.select_a_git_source')}
</div>
</div>
<div class="max-w-5xl mx-auto ">
<div class="title pb-8">Git App</div> <div class="title pb-8">Git App</div>
<div class="flex flex-wrap justify-center"> <div class="flex flex-wrap justify-center">
{#if !filteredSources || ownSources.length === 0} {#if !filteredSources || ownSources.length === 0}
@@ -192,7 +187,7 @@
</div> </div>
{/if} {/if}
</div> </div>
<div class="flex items-center"> <div class="flex flex-row items-center">
<div class="title py-4">Public Repository</div> <div class="title py-4">Public Repository</div>
<DocLink url="https://docs.coollabs.io/coolify/applications/#public-repository" /> <DocLink url="https://docs.coollabs.io/coolify/applications/#public-repository" />
</div> </div>

View File

@@ -94,7 +94,7 @@
} }
]; ];
function containerClass() { function containerClass() {
return 'text-white bg-transparent font-thin px-0'; return 'text-white bg-transparent font-thin px-0 w-full border-dashed border-coolgray-300';
} }
async function getUsage() { async function getUsage() {
@@ -294,84 +294,31 @@
} }
</script> </script>
<div class="flex items-center space-x-2 p-5 px-6 font-bold"> {#if $status.application.isRunning}
<div class="-mb-5 flex-col"> <div class="mx-auto max-w-6xl px-6 lg:my-0 my-4 lg:pt-0 pt-4 rounded">
<div class="md:max-w-64 truncate text-base tracking-tight md:text-2xl lg:block"> <div class="text-center">
Configuration <div class="stat w-64">
</div> <div class="stat-title">Used Memory / Memory Limit</div>
<span class="text-xs">{application.name}</span> <div class="stat-value text-xl">{usage?.MemUsage}</div>
</div> </div>
{#if application.gitSource?.htmlUrl && application.repository && application.branch}
<a
id="git"
href="{application.gitSource.htmlUrl}/{application.repository}/tree/{application.branch}"
target="_blank"
class="w-10"
>
{#if application.gitSource?.type === 'gitlab'}
<svg viewBox="0 0 128 128" class="icons">
<path
fill="#FC6D26"
d="M126.615 72.31l-7.034-21.647L105.64 7.76c-.716-2.206-3.84-2.206-4.556 0l-13.94 42.903H40.856L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664 1.385 72.31a4.792 4.792 0 001.74 5.358L64 121.894l60.874-44.227a4.793 4.793 0 001.74-5.357"
/><path fill="#E24329" d="M64 121.894l23.144-71.23H40.856L64 121.893z" /><path
fill="#FC6D26"
d="M64 121.894l-23.144-71.23H8.42L64 121.893z"
/><path
fill="#FCA326"
d="M8.42 50.663L1.384 72.31a4.79 4.79 0 001.74 5.357L64 121.894 8.42 50.664z"
/><path
fill="#E24329"
d="M8.42 50.663h32.436L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664z"
/><path fill="#FC6D26" d="M64 121.894l23.144-71.23h32.437L64 121.893z" /><path
fill="#FCA326"
d="M119.58 50.663l7.035 21.647a4.79 4.79 0 01-1.74 5.357L64 121.894l55.58-71.23z"
/><path
fill="#E24329"
d="M119.58 50.663H87.145l13.94-42.902c.717-2.206 3.84-2.206 4.557 0l13.94 42.903z"
/>
</svg>
{:else if application.gitSource?.type === 'github'}
<svg viewBox="0 0 128 128" class="icons">
<g fill="#ffffff"
><path
fill-rule="evenodd"
clip-rule="evenodd"
d="M64 5.103c-33.347 0-60.388 27.035-60.388 60.388 0 26.682 17.303 49.317 41.297 57.303 3.017.56 4.125-1.31 4.125-2.905 0-1.44-.056-6.197-.082-11.243-16.8 3.653-20.345-7.125-20.345-7.125-2.747-6.98-6.705-8.836-6.705-8.836-5.48-3.748.413-3.67.413-3.67 6.063.425 9.257 6.223 9.257 6.223 5.386 9.23 14.127 6.562 17.573 5.02.542-3.903 2.107-6.568 3.834-8.076-13.413-1.525-27.514-6.704-27.514-29.843 0-6.593 2.36-11.98 6.223-16.21-.628-1.52-2.695-7.662.584-15.98 0 0 5.07-1.623 16.61 6.19C53.7 35 58.867 34.327 64 34.304c5.13.023 10.3.694 15.127 2.033 11.526-7.813 16.59-6.19 16.59-6.19 3.287 8.317 1.22 14.46.593 15.98 3.872 4.23 6.215 9.617 6.215 16.21 0 23.194-14.127 28.3-27.574 29.796 2.167 1.874 4.097 5.55 4.097 11.183 0 8.08-.07 14.583-.07 16.572 0 1.607 1.088 3.49 4.148 2.897 23.98-7.994 41.263-30.622 41.263-57.294C124.388 32.14 97.35 5.104 64 5.104z"
/><path
d="M26.484 91.806c-.133.3-.605.39-1.035.185-.44-.196-.685-.605-.543-.906.13-.31.603-.395 1.04-.188.44.197.69.61.537.91zm2.446 2.729c-.287.267-.85.143-1.232-.28-.396-.42-.47-.983-.177-1.254.298-.266.844-.14 1.24.28.394.426.472.984.17 1.255zM31.312 98.012c-.37.258-.976.017-1.35-.52-.37-.538-.37-1.183.01-1.44.373-.258.97-.025 1.35.507.368.545.368 1.19-.01 1.452zm3.261 3.361c-.33.365-1.036.267-1.552-.23-.527-.487-.674-1.18-.343-1.544.336-.366 1.045-.264 1.564.23.527.486.686 1.18.333 1.543zm4.5 1.951c-.147.473-.825.688-1.51.486-.683-.207-1.13-.76-.99-1.238.14-.477.823-.7 1.512-.485.683.206 1.13.756.988 1.237zm4.943.361c.017.498-.563.91-1.28.92-.723.017-1.308-.387-1.315-.877 0-.503.568-.91 1.29-.924.717-.013 1.306.387 1.306.88zm4.598-.782c.086.485-.413.984-1.126 1.117-.7.13-1.35-.172-1.44-.653-.086-.498.422-.997 1.122-1.126.714-.123 1.354.17 1.444.663zm0 0"
/></g
>
</svg>
{/if}
</a>
<Tooltip triggeredBy="#git">Open on Git</Tooltip>
{/if}
</div>
<div class="mx-auto max-w-4xl px-6 py-4"> <div class="stat w-64">
<div class="text-2xl font-bold">Application Usage</div> <div class="stat-title">Used CPU</div>
<div class="text-center"> <div class="stat-value text-xl">{usage?.CPUPerc}</div>
<div class="stat w-64"> </div>
<div class="stat-title">Used Memory / Memory Limit</div>
<div class="stat-value text-xl">{usage?.MemUsage}</div>
</div>
<div class="stat w-64"> <div class="stat w-64">
<div class="stat-title">Used CPU</div> <div class="stat-title">Network IO</div>
<div class="stat-value text-xl">{usage?.CPUPerc}</div> <div class="stat-value text-xl">{usage?.NetIO}</div>
</div> </div>
<div class="stat w-64">
<div class="stat-title">Network IO</div>
<div class="stat-value text-xl">{usage?.NetIO}</div>
</div> </div>
</div> </div>
</div> {/if}
<div class="mx-auto max-w-4xl px-6"> <div class="mx-auto max-w-6xl px-6 pb-12">
<!-- svelte-ignore missing-declaration --> <!-- svelte-ignore missing-declaration -->
<form on:submit|preventDefault={handleSubmit} class="py-4"> <form on:submit|preventDefault={handleSubmit} class="py-4">
<div class="flex space-x-1 pb-5"> <div class="flex space-x-1 pb-5 items-center">
<div class="title">{$t('general')}</div> <h1 class="title">{$t('general')}</h1>
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<button <button
class="btn btn-sm" class="btn btn-sm"
@@ -384,18 +331,18 @@
> >
{/if} {/if}
</div> </div>
<div class="grid grid-flow-row gap-2 px-10">
<div class="grid grid-flow-row gap-2 lg:px-10 px-2 pr-5">
<div class="mt-2 grid grid-cols-2 items-center"> <div class="mt-2 grid grid-cols-2 items-center">
<label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label> <label for="name">{$t('forms.name')}</label>
<input name="name" id="name" bind:value={application.name} required /> <input name="name" id="name" class="w-full" bind:value={application.name} required />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="gitSource" class="text-base font-bold text-stone-100" <label for="gitSource">{$t('application.git_source')}</label>
>{$t('application.git_source')}</label
>
{#if isDisabled || application.settings.isPublicRepository} {#if isDisabled || application.settings.isPublicRepository}
<input <input
disabled={isDisabled || application.settings.isPublicRepository} disabled={isDisabled || application.settings.isPublicRepository}
class="w-full"
value={application.gitSource.name} value={application.gitSource.name}
/> />
{:else} {:else}
@@ -405,17 +352,16 @@
><input ><input
value={application.gitSource.name} value={application.gitSource.name}
id="gitSource" id="gitSource"
class="cursor-pointer hover:bg-coolgray-500" class="cursor-pointer hover:bg-coolgray-500 w-full"
/></a /></a
> >
{/if} {/if}
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="repository" class="text-base font-bold text-stone-100" <label for="repository">{$t('application.git_repository')}</label>
>{$t('application.git_repository')}</label
>
{#if isDisabled || application.settings.isPublicRepository} {#if isDisabled || application.settings.isPublicRepository}
<input <input
class="w-full"
disabled={isDisabled || application.settings.isPublicRepository} disabled={isDisabled || application.settings.isPublicRepository}
value="{application.repository}/{application.branch}" value="{application.repository}/{application.branch}"
/> />
@@ -426,46 +372,42 @@
><input ><input
value="{application.repository}/{application.branch}" value="{application.repository}/{application.branch}"
id="repository" id="repository"
class="cursor-pointer hover:bg-coolgray-500" class="cursor-pointer hover:bg-coolgray-500 w-full"
/></a /></a
> >
{/if} {/if}
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="buildPack" class="text-base font-bold text-stone-100" <label for="buildPack">{$t('application.build_pack')}</label>
>{$t('application.build_pack')}</label
>
{#if isDisabled} {#if isDisabled}
<input class="capitalize" disabled={isDisabled} value={application.buildPack} /> <input class="uppercase w-full" disabled={isDisabled} value={application.buildPack} />
{:else} {:else}
<a <a
href={`/applications/${id}/configuration/buildpack?from=/applications/${id}`} href={`/applications/${id}/configuration/buildpack?from=/applications/${id}`}
class="no-underline " class="no-underline"
> >
<input <input
value={application.buildPack} value={application.buildPack}
id="buildPack" id="buildPack"
class="cursor-pointer hover:bg-coolgray-500 capitalize" class="cursor-pointer hover:bg-coolgray-500 capitalize w-full"
/></a /></a
> >
{/if} {/if}
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="destination" class="text-base font-bold text-stone-100" <label for="destination">{$t('application.destination')}</label>
>{$t('application.destination')}</label
>
<div class="no-underline"> <div class="no-underline">
<input <input
value={application.destinationDocker.name} value={application.destinationDocker.name}
id="destination" id="destination"
disabled disabled
class="bg-transparent" class="bg-transparent w-full"
/> />
</div> </div>
</div> </div>
{#if application.buildCommand || application.buildPack === 'rust' || application.buildPack === 'laravel'} {#if application.buildCommand || application.buildPack === 'rust' || application.buildPack === 'laravel'}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="baseBuildImage" class="text-base font-bold text-stone-100" <label for="baseBuildImage"
>{$t('application.base_build_image')} >{$t('application.base_build_image')}
<Explainer <Explainer
explanation={application.buildPack === 'laravel' explanation={application.buildPack === 'laravel'
@@ -473,24 +415,21 @@
: 'Image that will be used during the build process.'} : 'Image that will be used during the build process.'}
/> />
</label> </label>
<Select
<div class="custom-select-wrapper"> {isDisabled}
<Select containerClasses={isDisabled && containerClass()}
{isDisabled} id="baseBuildImages"
containerClasses={isDisabled && containerClass()} showIndicator={!$status.application.isRunning}
id="baseBuildImages" items={application.baseBuildImages}
showIndicator={!$status.application.isRunning} on:select={selectBaseBuildImage}
items={application.baseBuildImages} value={application.baseBuildImage}
on:select={selectBaseBuildImage} isClearable={false}
value={application.baseBuildImage} />
isClearable={false}
/>
</div>
</div> </div>
{/if} {/if}
{#if application.buildPack !== 'docker'} {#if application.buildPack !== 'docker'}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="baseImage" class="text-base font-bold text-stone-100" <label for="baseImage"
>{$t('application.base_image')} >{$t('application.base_image')}
<Explainer explanation={'Image that will be used for the deployment.'} /></label <Explainer explanation={'Image that will be used for the deployment.'} /></label
> >
@@ -510,7 +449,7 @@
{/if} {/if}
{#if application.buildPack !== 'docker' && (application.buildPack === 'nextjs' || application.buildPack === 'nuxtjs')} {#if application.buildPack !== 'docker' && (application.buildPack === 'nextjs' || application.buildPack === 'nuxtjs')}
<div class="grid grid-cols-2 items-center pb-8"> <div class="grid grid-cols-2 items-center pb-8">
<label for="deploymentType" class="text-base font-bold text-stone-100" <label for="deploymentType"
>Deployment Type >Deployment Type
<Explainer <Explainer
explanation={"Defines how to deploy your application. <br><br><span class='text-green-500 font-bold'>Static</span> is for static websites, <span class='text-green-500 font-bold'>node</span> is for server-side applications."} explanation={"Defines how to deploy your application. <br><br><span class='text-green-500 font-bold'>Static</span> is for static websites, <span class='text-green-500 font-bold'>node</span> is for server-side applications."}
@@ -550,7 +489,7 @@
> >
{#if application.connectedDatabase} {#if application.connectedDatabase}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="baseImage" class="text-base font-bold text-stone-100" <label for="baseImage"
>Base Database >Base Database
<Explainer <Explainer
explanation={'The name of the database that will be used as base when branching.'} explanation={'The name of the database that will be used as base when branching.'}
@@ -572,9 +511,9 @@
{/if} {/if}
</div> </div>
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">{$t('application.application')}</div> <h1 class="title">{$t('application.application')}</h1>
</div> </div>
<div class="grid grid-flow-row gap-2 px-10"> <div class="grid grid-flow-row gap-2 lg:px-10 px-2 pr-5">
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<Setting <Setting
id="isBot" id="isBot"
@@ -594,13 +533,13 @@
isCenter={false} isCenter={false}
bind:setting={dualCerts} bind:setting={dualCerts}
title={$t('application.ssl_www_and_non_www')} title={$t('application.ssl_www_and_non_www')}
description="It will generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-settings'>both DNS entries</span> set in advance.<br><br>Useful if you expect to have visitors on both." description="Generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-settings'>both DNS entries</span> set in advance.<br><br>Useful if you expect to have visitors on both."
on:click={() => !$status.application.isRunning && changeSettings('dualCerts')} on:click={() => !$status.application.isRunning && changeSettings('dualCerts')}
/> />
</div> </div>
{#if !isBot} {#if !isBot}
<div class="grid grid-cols-2 items-center pb-8"> <div class="grid grid-cols-2 items-center pb-8">
<label for="fqdn" class="text-base font-bold text-stone-100" <label for="fqdn"
>{$t('application.url_fqdn')} >{$t('application.url_fqdn')}
<Explainer <Explainer
explanation={"If you specify <span class='text-settings font-bold'>https</span>, the application will be accessible only over https.<br>SSL certificate will be generated automatically.<br><br>If you specify <span class='text-settings font-bold'>www</span>, the application will be redirected (302) from non-www and vice versa.<br><br>To modify the domain, you must first stop the application.<br><br><span class='text-settings font-bold'>You must set your DNS to point to the server IP in advance.</span>"} explanation={"If you specify <span class='text-settings font-bold'>https</span>, the application will be accessible only over https.<br>SSL certificate will be generated automatically.<br><br>If you specify <span class='text-settings font-bold'>www</span>, the application will be redirected (302) from non-www and vice versa.<br><br>To modify the domain, you must first stop the application.<br><br><span class='text-settings font-bold'>You must set your DNS to point to the server IP in advance.</span>"}
@@ -608,6 +547,8 @@
</label> </label>
<div> <div>
<input <input
class="w-full"
required={!application.settings.isBot}
readonly={isDisabled} readonly={isDisabled}
disabled={isDisabled} disabled={isDisabled}
name="fqdn" name="fqdn"
@@ -655,14 +596,14 @@
{/if} {/if}
{#if application.buildPack === 'python'} {#if application.buildPack === 'python'}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="pythonModule" class="text-base font-bold text-stone-100">WSGI / ASGI</label> <label for="pythonModule">WSGI / ASGI</label>
<div class="custom-select-wrapper"> <div class="custom-select-wrapper">
<Select id="wsgi" items={wsgis} on:select={selectWSGI} value={application.pythonWSGI} /> <Select id="wsgi" items={wsgis} on:select={selectWSGI} value={application.pythonWSGI} />
</div> </div>
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="pythonModule" class="text-base font-bold text-stone-100">Module</label> <label for="pythonModule">Module</label>
<input <input
disabled={isDisabled} disabled={isDisabled}
readonly={!$appSession.isAdmin} readonly={!$appSession.isAdmin}
@@ -675,7 +616,7 @@
</div> </div>
{#if application.pythonWSGI?.toLowerCase() === 'gunicorn'} {#if application.pythonWSGI?.toLowerCase() === 'gunicorn'}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="pythonVariable" class="text-base font-bold text-stone-100">Variable</label> <label for="pythonVariable">Variable</label>
<input <input
disabled={isDisabled} disabled={isDisabled}
readonly={!$appSession.isAdmin} readonly={!$appSession.isAdmin}
@@ -689,7 +630,7 @@
{/if} {/if}
{#if application.pythonWSGI?.toLowerCase() === 'uvicorn'} {#if application.pythonWSGI?.toLowerCase() === 'uvicorn'}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="pythonVariable" class="text-base font-bold text-stone-100">Variable</label> <label for="pythonVariable">Variable</label>
<input <input
disabled={isDisabled} disabled={isDisabled}
readonly={!$appSession.isAdmin} readonly={!$appSession.isAdmin}
@@ -704,11 +645,12 @@
{/if} {/if}
{#if !staticDeployments.includes(application.buildPack)} {#if !staticDeployments.includes(application.buildPack)}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="port" class="text-base font-bold text-stone-100" <label for="port"
>{$t('forms.port')} >{$t('forms.port')}
<Explainer explanation={'The port your application listens on.'} /></label <Explainer explanation={'The port your application listens on.'} /></label
> >
<input <input
class="w-full"
disabled={isDisabled} disabled={isDisabled}
readonly={!$appSession.isAdmin} readonly={!$appSession.isAdmin}
name="port" name="port"
@@ -718,13 +660,14 @@
/> />
</div> </div>
{/if} {/if}
<div class="grid grid-cols-2 items-center pb-8"> <div class="grid grid-cols-2 items-center">
<label for="exposePort" class="text-base font-bold text-stone-100" <label for="exposePort"
>Exposed Port <Explainer >Exposed Port <Explainer
explanation={'You can expose your application to a port on the host system.<br><br>Useful if you would like to use your own reverse proxy or tunnel and also in development mode. Otherwise leave empty.'} explanation={'You can expose your application to a port on the host system.<br><br>Useful if you would like to use your own reverse proxy or tunnel and also in development mode. Otherwise leave empty.'}
/></label /></label
> >
<input <input
class="w-full"
readonly={!$appSession.isAdmin && !$status.application.isRunning} readonly={!$appSession.isAdmin && !$status.application.isRunning}
disabled={isDisabled} disabled={isDisabled}
name="exposePort" name="exposePort"
@@ -735,10 +678,9 @@
</div> </div>
{#if !notNodeDeployments.includes(application.buildPack)} {#if !notNodeDeployments.includes(application.buildPack)}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="installCommand" class="text-base font-bold text-stone-100" <label for="installCommand">{$t('application.install_command')}</label>
>{$t('application.install_command')}</label
>
<input <input
class="w-full"
disabled={isDisabled} disabled={isDisabled}
readonly={!$appSession.isAdmin} readonly={!$appSession.isAdmin}
name="installCommand" name="installCommand"
@@ -748,10 +690,9 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="buildCommand" class="text-base font-bold text-stone-100" <label for="buildCommand">{$t('application.build_command')}</label>
>{$t('application.build_command')}</label
>
<input <input
class="w-full"
disabled={isDisabled} disabled={isDisabled}
readonly={!$appSession.isAdmin} readonly={!$appSession.isAdmin}
name="buildCommand" name="buildCommand"
@@ -761,10 +702,9 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center pb-8"> <div class="grid grid-cols-2 items-center pb-8">
<label for="startCommand" class="text-base font-bold text-stone-100" <label for="startCommand">{$t('application.start_command')}</label>
>{$t('application.start_command')}</label
>
<input <input
class="w-full"
disabled={isDisabled} disabled={isDisabled}
readonly={!$appSession.isAdmin} readonly={!$appSession.isAdmin}
name="startCommand" name="startCommand"
@@ -776,12 +716,13 @@
{/if} {/if}
{#if application.buildPack === 'docker'} {#if application.buildPack === 'docker'}
<div class="grid grid-cols-2 items-center pt-4"> <div class="grid grid-cols-2 items-center pt-4">
<label for="dockerFileLocation" class="text-base font-bold text-stone-100" <label for="dockerFileLocation"
>Dockerfile Location <Explainer >Dockerfile Location <Explainer
explanation={"Should be absolute path, like <span class='text-settings font-bold'>/data/Dockerfile</span> or <span class='text-settings font-bold'>/Dockerfile.</span>"} explanation={"Should be absolute path, like <span class='text-settings font-bold'>/data/Dockerfile</span> or <span class='text-settings font-bold'>/Dockerfile.</span>"}
/></label /></label
> >
<input <input
class="w-full"
disabled={isDisabled} disabled={isDisabled}
readonly={!$appSession.isAdmin} readonly={!$appSession.isAdmin}
name="dockerFileLocation" name="dockerFileLocation"
@@ -793,8 +734,9 @@
{/if} {/if}
{#if application.buildPack === 'deno'} {#if application.buildPack === 'deno'}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="denoMainFile" class="text-base font-bold text-stone-100">Main File</label> <label for="denoMainFile">Main File</label>
<input <input
class="w-full"
disabled={isDisabled} disabled={isDisabled}
readonly={!$appSession.isAdmin} readonly={!$appSession.isAdmin}
name="denoMainFile" name="denoMainFile"
@@ -804,12 +746,13 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="denoOptions" class="text-base font-bold text-stone-100" <label for="denoOptions"
>Arguments <Explainer >Arguments <Explainer
explanation={"List of arguments to pass to <span class='text-settings font-bold'>deno run</span> command. Could include permissions, configurations files, etc."} explanation={"List of arguments to pass to <span class='text-settings font-bold'>deno run</span> command. Could include permissions, configurations files, etc."}
/></label /></label
> >
<input <input
class="w-full"
disabled={isDisabled} disabled={isDisabled}
readonly={!$appSession.isAdmin} readonly={!$appSession.isAdmin}
name="denoOptions" name="denoOptions"
@@ -822,7 +765,7 @@
{#if application.buildPack !== 'laravel' && application.buildPack !== 'heroku'} {#if application.buildPack !== 'laravel' && application.buildPack !== 'heroku'}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<div class="flex-col"> <div class="flex-col">
<label for="baseDirectory" class="pt-2 text-base font-bold text-stone-100" <label for="baseDirectory"
>{$t('forms.base_directory')} >{$t('forms.base_directory')}
<Explainer <Explainer
explanation={"Directory to use as the base for all commands.<br>Could be useful with <span class='text-settings font-bold'>monorepos</span>."} explanation={"Directory to use as the base for all commands.<br>Could be useful with <span class='text-settings font-bold'>monorepos</span>."}
@@ -830,6 +773,7 @@
> >
</div> </div>
<input <input
class="w-full"
disabled={isDisabled} disabled={isDisabled}
readonly={!$appSession.isAdmin} readonly={!$appSession.isAdmin}
name="baseDirectory" name="baseDirectory"
@@ -842,7 +786,7 @@
{#if !notNodeDeployments.includes(application.buildPack)} {#if !notNodeDeployments.includes(application.buildPack)}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<div class="flex-col"> <div class="flex-col">
<label for="publishDirectory" class="pt-2 text-base font-bold text-stone-100" <label for="publishDirectory"
>{$t('forms.publish_directory')} >{$t('forms.publish_directory')}
<Explainer <Explainer
explanation={"Directory containing all the assets for deployment. <br> For example: <span class='text-settings font-bold'>dist</span>,<span class='text-settings font-bold'>_site</span> or <span class='text-settings font-bold'>public</span>."} explanation={"Directory containing all the assets for deployment. <br> For example: <span class='text-settings font-bold'>dist</span>,<span class='text-settings font-bold'>_site</span> or <span class='text-settings font-bold'>public</span>."}
@@ -851,6 +795,7 @@
</div> </div>
<input <input
class="w-full"
disabled={isDisabled} disabled={isDisabled}
readonly={!$appSession.isAdmin} readonly={!$appSession.isAdmin}
name="publishDirectory" name="publishDirectory"
@@ -866,7 +811,7 @@
<div class="flex space-x-1 pb-5 font-bold"> <div class="flex space-x-1 pb-5 font-bold">
<div class="title">{$t('application.features')}</div> <div class="title">{$t('application.features')}</div>
</div> </div>
<div class="px-10 pb-10"> <div class="lg:px-10 px-2 lg:pb-10 pb-6">
{#if !application.settings.isPublicRepository} {#if !application.settings.isPublicRepository}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<Setting <Setting
@@ -891,7 +836,7 @@
/> />
</div> </div>
{/if} {/if}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center w-full">
<Setting <Setting
id="debug" id="debug"
isCenter={false} isCenter={false}

View File

@@ -160,10 +160,7 @@
{/if} {/if}
</div> </div>
{#if logs.length > 0} {#if logs.length > 0}
<div <div class="font-mono w-full rounder bg-coolgray-200 p-5 overflow-x-auto overflox-y-auto max-h-[80vh] rounded-md mb-20 flex flex-col whitespace-nowrap -mt-12 scrollbar-thumb-coollabs scrollbar-track-coolgray-200 scrollbar-w-1">
class="font-mono leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12 overflow-y-scroll scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200"
bind:this={logsEl}
>
{#each logs as log} {#each logs as log}
{#if fromDb} {#if fromDb}
<div>{log.line + '\n'}</div> <div>{log.line + '\n'}</div>
@@ -173,11 +170,9 @@
{/each} {/each}
</div> </div>
{:else} {:else}
<div <div class="font-mono w-full rounder bg-coolgray-200 p-5 overflow-x-auto overflox-y-auto max-h-[80vh] rounded-md mb-20 flex flex-col whitespace-nowrap -mt-12 scrollbar-thumb-coollabs scrollbar-track-coolgray-200 scrollbar-w-1">
class="font-mono leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12 overflow-y-scroll scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200" No logs found.
> </div>
No logs found.
</div>
{/if} {/if}
{/if} {/if}
</div> </div>

View File

@@ -107,57 +107,6 @@
} }
</script> </script>
<div class="flex items-center space-x-2 p-5 px-6 font-bold">
<div class="-mb-5 flex-col">
<div class="md:max-w-64 truncate text-base tracking-tight md:text-2xl lg:block">
{$t('application.build_logs')}
</div>
<span class="text-xs">{application.name} </span>
</div>
{#if application.gitSource?.htmlUrl && application.repository && application.branch}
<a
href="{application.gitSource.htmlUrl}/{application.repository}/tree/{application.branch}"
target="_blank"
class="w-10"
>
{#if application.gitSource?.type === 'gitlab'}
<svg viewBox="0 0 128 128" class="icons">
<path
fill="#FC6D26"
d="M126.615 72.31l-7.034-21.647L105.64 7.76c-.716-2.206-3.84-2.206-4.556 0l-13.94 42.903H40.856L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664 1.385 72.31a4.792 4.792 0 001.74 5.358L64 121.894l60.874-44.227a4.793 4.793 0 001.74-5.357"
/><path fill="#E24329" d="M64 121.894l23.144-71.23H40.856L64 121.893z" /><path
fill="#FC6D26"
d="M64 121.894l-23.144-71.23H8.42L64 121.893z"
/><path
fill="#FCA326"
d="M8.42 50.663L1.384 72.31a4.79 4.79 0 001.74 5.357L64 121.894 8.42 50.664z"
/><path
fill="#E24329"
d="M8.42 50.663h32.436L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664z"
/><path fill="#FC6D26" d="M64 121.894l23.144-71.23h32.437L64 121.893z" /><path
fill="#FCA326"
d="M119.58 50.663l7.035 21.647a4.79 4.79 0 01-1.74 5.357L64 121.894l55.58-71.23z"
/><path
fill="#E24329"
d="M119.58 50.663H87.145l13.94-42.902c.717-2.206 3.84-2.206 4.557 0l13.94 42.903z"
/>
</svg>
{:else if application.gitSource?.type === 'github'}
<svg viewBox="0 0 128 128" class="icons">
<g fill="#ffffff"
><path
fill-rule="evenodd"
clip-rule="evenodd"
d="M64 5.103c-33.347 0-60.388 27.035-60.388 60.388 0 26.682 17.303 49.317 41.297 57.303 3.017.56 4.125-1.31 4.125-2.905 0-1.44-.056-6.197-.082-11.243-16.8 3.653-20.345-7.125-20.345-7.125-2.747-6.98-6.705-8.836-6.705-8.836-5.48-3.748.413-3.67.413-3.67 6.063.425 9.257 6.223 9.257 6.223 5.386 9.23 14.127 6.562 17.573 5.02.542-3.903 2.107-6.568 3.834-8.076-13.413-1.525-27.514-6.704-27.514-29.843 0-6.593 2.36-11.98 6.223-16.21-.628-1.52-2.695-7.662.584-15.98 0 0 5.07-1.623 16.61 6.19C53.7 35 58.867 34.327 64 34.304c5.13.023 10.3.694 15.127 2.033 11.526-7.813 16.59-6.19 16.59-6.19 3.287 8.317 1.22 14.46.593 15.98 3.872 4.23 6.215 9.617 6.215 16.21 0 23.194-14.127 28.3-27.574 29.796 2.167 1.874 4.097 5.55 4.097 11.183 0 8.08-.07 14.583-.07 16.572 0 1.607 1.088 3.49 4.148 2.897 23.98-7.994 41.263-30.622 41.263-57.294C124.388 32.14 97.35 5.104 64 5.104z"
/><path
d="M26.484 91.806c-.133.3-.605.39-1.035.185-.44-.196-.685-.605-.543-.906.13-.31.603-.395 1.04-.188.44.197.69.61.537.91zm2.446 2.729c-.287.267-.85.143-1.232-.28-.396-.42-.47-.983-.177-1.254.298-.266.844-.14 1.24.28.394.426.472.984.17 1.255zM31.312 98.012c-.37.258-.976.017-1.35-.52-.37-.538-.37-1.183.01-1.44.373-.258.97-.025 1.35.507.368.545.368 1.19-.01 1.452zm3.261 3.361c-.33.365-1.036.267-1.552-.23-.527-.487-.674-1.18-.343-1.544.336-.366 1.045-.264 1.564.23.527.486.686 1.18.333 1.543zm4.5 1.951c-.147.473-.825.688-1.51.486-.683-.207-1.13-.76-.99-1.238.14-.477.823-.7 1.512-.485.683.206 1.13.756.988 1.237zm4.943.361c.017.498-.563.91-1.28.92-.723.017-1.308-.387-1.315-.877 0-.503.568-.91 1.29-.924.717-.013 1.306.387 1.306.88zm4.598-.782c.086.485-.413.984-1.126 1.117-.7.13-1.35-.172-1.44-.653-.086-.498.422-.997 1.122-1.126.714-.123 1.354.17 1.444.663zm0 0"
/></g
>
</svg>
{/if}
</a>
{/if}
</div>
<div class="block flex-row justify-start space-x-2 px-5 pt-6 sm:px-10 md:flex"> <div class="block flex-row justify-start space-x-2 px-5 pt-6 sm:px-10 md:flex">
<div class="mb-4 min-w-[16rem] space-y-2 md:mb-0 "> <div class="mb-4 min-w-[16rem] space-y-2 md:mb-0 ">
<button class="btn btn-sm text-xs w-full bg-error" on:click={resetQueue} <button class="btn btn-sm text-xs w-full bg-error" on:click={resetQueue}

View File

@@ -91,57 +91,7 @@
} }
</script> </script>
<div class="flex h-20 items-center space-x-2 p-5 px-6 font-bold">
<div class="-mb-5 flex-col">
<div class="md:max-w-64 truncate text-base tracking-tight md:text-2xl lg:block">
Application Logs
</div>
<span class="text-xs">{application.name}</span>
</div>
{#if application.gitSource?.htmlUrl && application.repository && application.branch}
<a
href="{application.gitSource.htmlUrl}/{application.repository}/tree/{application.branch}"
target="_blank"
class="w-10"
>
{#if application.gitSource?.type === 'gitlab'}
<svg viewBox="0 0 128 128" class="icons">
<path
fill="#FC6D26"
d="M126.615 72.31l-7.034-21.647L105.64 7.76c-.716-2.206-3.84-2.206-4.556 0l-13.94 42.903H40.856L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664 1.385 72.31a4.792 4.792 0 001.74 5.358L64 121.894l60.874-44.227a4.793 4.793 0 001.74-5.357"
/><path fill="#E24329" d="M64 121.894l23.144-71.23H40.856L64 121.893z" /><path
fill="#FC6D26"
d="M64 121.894l-23.144-71.23H8.42L64 121.893z"
/><path
fill="#FCA326"
d="M8.42 50.663L1.384 72.31a4.79 4.79 0 001.74 5.357L64 121.894 8.42 50.664z"
/><path
fill="#E24329"
d="M8.42 50.663h32.436L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664z"
/><path fill="#FC6D26" d="M64 121.894l23.144-71.23h32.437L64 121.893z" /><path
fill="#FCA326"
d="M119.58 50.663l7.035 21.647a4.79 4.79 0 01-1.74 5.357L64 121.894l55.58-71.23z"
/><path
fill="#E24329"
d="M119.58 50.663H87.145l13.94-42.902c.717-2.206 3.84-2.206 4.557 0l13.94 42.903z"
/>
</svg>
{:else if application.gitSource?.type === 'github'}
<svg viewBox="0 0 128 128" class="icons">
<g fill="#ffffff"
><path
fill-rule="evenodd"
clip-rule="evenodd"
d="M64 5.103c-33.347 0-60.388 27.035-60.388 60.388 0 26.682 17.303 49.317 41.297 57.303 3.017.56 4.125-1.31 4.125-2.905 0-1.44-.056-6.197-.082-11.243-16.8 3.653-20.345-7.125-20.345-7.125-2.747-6.98-6.705-8.836-6.705-8.836-5.48-3.748.413-3.67.413-3.67 6.063.425 9.257 6.223 9.257 6.223 5.386 9.23 14.127 6.562 17.573 5.02.542-3.903 2.107-6.568 3.834-8.076-13.413-1.525-27.514-6.704-27.514-29.843 0-6.593 2.36-11.98 6.223-16.21-.628-1.52-2.695-7.662.584-15.98 0 0 5.07-1.623 16.61 6.19C53.7 35 58.867 34.327 64 34.304c5.13.023 10.3.694 15.127 2.033 11.526-7.813 16.59-6.19 16.59-6.19 3.287 8.317 1.22 14.46.593 15.98 3.872 4.23 6.215 9.617 6.215 16.21 0 23.194-14.127 28.3-27.574 29.796 2.167 1.874 4.097 5.55 4.097 11.183 0 8.08-.07 14.583-.07 16.572 0 1.607 1.088 3.49 4.148 2.897 23.98-7.994 41.263-30.622 41.263-57.294C124.388 32.14 97.35 5.104 64 5.104z"
/><path
d="M26.484 91.806c-.133.3-.605.39-1.035.185-.44-.196-.685-.605-.543-.906.13-.31.603-.395 1.04-.188.44.197.69.61.537.91zm2.446 2.729c-.287.267-.85.143-1.232-.28-.396-.42-.47-.983-.177-1.254.298-.266.844-.14 1.24.28.394.426.472.984.17 1.255zM31.312 98.012c-.37.258-.976.017-1.35-.52-.37-.538-.37-1.183.01-1.44.373-.258.97-.025 1.35.507.368.545.368 1.19-.01 1.452zm3.261 3.361c-.33.365-1.036.267-1.552-.23-.527-.487-.674-1.18-.343-1.544.336-.366 1.045-.264 1.564.23.527.486.686 1.18.333 1.543zm4.5 1.951c-.147.473-.825.688-1.51.486-.683-.207-1.13-.76-.99-1.238.14-.477.823-.7 1.512-.485.683.206 1.13.756.988 1.237zm4.943.361c.017.498-.563.91-1.28.92-.723.017-1.308-.387-1.315-.877 0-.503.568-.91 1.29-.924.717-.013 1.306.387 1.306.88zm4.598-.782c.086.485-.413.984-1.126 1.117-.7.13-1.35-.172-1.44-.653-.086-.498.422-.997 1.122-1.126.714-.123 1.354.17 1.444.663zm0 0"
/></g
>
</svg>
{/if}
</a>
{/if}
</div>
<div class="flex flex-row justify-center space-x-2 px-10 pt-6"> <div class="flex flex-row justify-center space-x-2 px-10 pt-6">
{#if logs.length === 0} {#if logs.length === 0}
<div class="text-xl font-bold tracking-tighter">{$t('application.build.waiting_logs')}</div> <div class="text-xl font-bold tracking-tighter">{$t('application.build.waiting_logs')}</div>
@@ -177,16 +127,10 @@
</button> </button>
<Tooltip triggeredBy="#follow">Follow Logs</Tooltip> <Tooltip triggeredBy="#follow">Follow Logs</Tooltip>
</div> </div>
<div <div class="font-mono w-full rounder bg-coolgray-200 p-5 overflow-x-auto overflox-y-auto max-h-[80vh] rounded-md mb-20 flex flex-col whitespace-nowrap -mt-12 scrollbar-thumb-coollabs scrollbar-track-coolgray-200 scrollbar-w-1">
class="font-mono w-full leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12 overflow-y-scroll scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200" {#each logs as log}
bind:this={logsEl} <p>{log + '\n'}</p>
on:scroll={detect} {/each}
>
<div class="px-2 pr-14">
{#each logs as log}
{log + '\n'}
{/each}
</div>
</div> </div>
</div> </div>
{/if} {/if}

View File

@@ -29,6 +29,7 @@
import SimpleExplainer from '$lib/components/SimpleExplainer.svelte'; import SimpleExplainer from '$lib/components/SimpleExplainer.svelte';
import Tooltip from '$lib/components/Tooltip.svelte'; import Tooltip from '$lib/components/Tooltip.svelte';
import DeleteIcon from '$lib/components/DeleteIcon.svelte'; import DeleteIcon from '$lib/components/DeleteIcon.svelte';
import Explainer from '$lib/components/Explainer.svelte';
const { id } = $page.params; const { id } = $page.params;
let loadBuildingStatusInterval: any = null; let loadBuildingStatusInterval: any = null;
@@ -119,7 +120,7 @@
return 'error'; return 'error';
} finally { } finally {
numberOfGetStatus--; numberOfGetStatus--;
status = status status = status;
} }
} }
async function restartPreview(preview: any) { async function restartPreview(preview: any) {
@@ -176,56 +177,12 @@
}); });
</script> </script>
<div class="flex items-center space-x-2 p-5 px-6 font-bold"> <div class="flex justify-center">
<div class="-mb-5 flex-col"> <SimpleExplainer
<div class="md:max-w-64 truncate text-base tracking-tight md:text-2xl lg:block"> text={applicationSecrets && applicationSecrets.length === 0
Preview Deployments ? "To have Preview Secerts, please add them to the main application. <br><br>Useful for creating <span class='text-green-500 font-bold'>staging</span> environments."
</div> : "These values overwrite application secrets in PR/MR deployments. <br>Useful for creating <span class='text-green-500 font-bold'>staging</span> environments."}
<span class="text-xs">{application?.name}</span> />
</div>
{#if application.gitSource?.htmlUrl && application.repository && application.branch}
<a
href="{application.gitSource.htmlUrl}/{application.repository}/tree/{application.branch}"
target="_blank"
class="w-10"
>
{#if application.gitSource?.type === 'gitlab'}
<svg viewBox="0 0 128 128" class="icons">
<path
fill="#FC6D26"
d="M126.615 72.31l-7.034-21.647L105.64 7.76c-.716-2.206-3.84-2.206-4.556 0l-13.94 42.903H40.856L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664 1.385 72.31a4.792 4.792 0 001.74 5.358L64 121.894l60.874-44.227a4.793 4.793 0 001.74-5.357"
/><path fill="#E24329" d="M64 121.894l23.144-71.23H40.856L64 121.893z" /><path
fill="#FC6D26"
d="M64 121.894l-23.144-71.23H8.42L64 121.893z"
/><path
fill="#FCA326"
d="M8.42 50.663L1.384 72.31a4.79 4.79 0 001.74 5.357L64 121.894 8.42 50.664z"
/><path
fill="#E24329"
d="M8.42 50.663h32.436L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664z"
/><path fill="#FC6D26" d="M64 121.894l23.144-71.23h32.437L64 121.893z" /><path
fill="#FCA326"
d="M119.58 50.663l7.035 21.647a4.79 4.79 0 01-1.74 5.357L64 121.894l55.58-71.23z"
/><path
fill="#E24329"
d="M119.58 50.663H87.145l13.94-42.902c.717-2.206 3.84-2.206 4.557 0l13.94 42.903z"
/>
</svg>
{:else if application.gitSource?.type === 'github'}
<svg viewBox="0 0 128 128" class="icons">
<g fill="#ffffff"
><path
fill-rule="evenodd"
clip-rule="evenodd"
d="M64 5.103c-33.347 0-60.388 27.035-60.388 60.388 0 26.682 17.303 49.317 41.297 57.303 3.017.56 4.125-1.31 4.125-2.905 0-1.44-.056-6.197-.082-11.243-16.8 3.653-20.345-7.125-20.345-7.125-2.747-6.98-6.705-8.836-6.705-8.836-5.48-3.748.413-3.67.413-3.67 6.063.425 9.257 6.223 9.257 6.223 5.386 9.23 14.127 6.562 17.573 5.02.542-3.903 2.107-6.568 3.834-8.076-13.413-1.525-27.514-6.704-27.514-29.843 0-6.593 2.36-11.98 6.223-16.21-.628-1.52-2.695-7.662.584-15.98 0 0 5.07-1.623 16.61 6.19C53.7 35 58.867 34.327 64 34.304c5.13.023 10.3.694 15.127 2.033 11.526-7.813 16.59-6.19 16.59-6.19 3.287 8.317 1.22 14.46.593 15.98 3.872 4.23 6.215 9.617 6.215 16.21 0 23.194-14.127 28.3-27.574 29.796 2.167 1.874 4.097 5.55 4.097 11.183 0 8.08-.07 14.583-.07 16.572 0 1.607 1.088 3.49 4.148 2.897 23.98-7.994 41.263-30.622 41.263-57.294C124.388 32.14 97.35 5.104 64 5.104z"
/><path
d="M26.484 91.806c-.133.3-.605.39-1.035.185-.44-.196-.685-.605-.543-.906.13-.31.603-.395 1.04-.188.44.197.69.61.537.91zm2.446 2.729c-.287.267-.85.143-1.232-.28-.396-.42-.47-.983-.177-1.254.298-.266.844-.14 1.24.28.394.426.472.984.17 1.255zM31.312 98.012c-.37.258-.976.017-1.35-.52-.37-.538-.37-1.183.01-1.44.373-.258.97-.025 1.35.507.368.545.368 1.19-.01 1.452zm3.261 3.361c-.33.365-1.036.267-1.552-.23-.527-.487-.674-1.18-.343-1.544.336-.366 1.045-.264 1.564.23.527.486.686 1.18.333 1.543zm4.5 1.951c-.147.473-.825.688-1.51.486-.683-.207-1.13-.76-.99-1.238.14-.477.823-.7 1.512-.485.683.206 1.13.756.988 1.237zm4.943.361c.017.498-.563.91-1.28.92-.723.017-1.308-.387-1.315-.877 0-.503.568-.91 1.29-.924.717-.013 1.306.387 1.306.88zm4.598-.782c.086.485-.413.984-1.126 1.117-.7.13-1.35-.172-1.44-.653-.086-.498.422-.997 1.122-1.126.714-.123 1.354.17 1.444.663zm0 0"
/></g
>
</svg>
{/if}
</a>
{/if}
</div> </div>
{#if loading.init} {#if loading.init}
<div class="mx-auto max-w-6xl px-6 pt-4"> <div class="mx-auto max-w-6xl px-6 pt-4">
@@ -233,21 +190,8 @@
</div> </div>
{:else} {:else}
<div class="mx-auto max-w-6xl px-6 pt-4"> <div class="mx-auto max-w-6xl px-6 pt-4">
<div class="flex justify-center py-4 text-center">
<SimpleExplainer
customClass="w-full"
text={applicationSecrets.length === 0
? "You can add secrets to PR/MR deployments. Please add secrets to the application first. <br>Useful for creating <span class='text-green-500 font-bold'>staging</span> environments."
: "These values overwrite application secrets in PR/MR deployments. <br>Useful for creating <span class='text-green-500 font-bold'>staging</span> environments."}
/>
</div>
<div class="text-center"> <div class="text-center">
<SimpleExplainer <button class="btn btn-sm bg-coollabs" on:click={loadPreviewsFromDocker}>Load Previews</button
customClass="w-full"
text={'If your preview is not shown, try load them directly from Docker Engine.<br>(Changed previews process flow in <span class="font-bold text-white">v3.10.4</span>)'}
/>
<button class="btn btn-sm bg-coollabs" on:click={loadPreviewsFromDocker}
>Fetch Previews</button
> >
</div> </div>
{#if applicationSecrets.length !== 0} {#if applicationSecrets.length !== 0}
@@ -427,10 +371,6 @@
</div> </div>
{/each} {/each}
</div> </div>
{:else}
<div class="flex-col">
<div class="text-center font-bold text-xl pb-10">Previews will shown here.</div>
</div>
{/if} {/if}
</div> </div>
{/if} {/if}

View File

@@ -67,87 +67,38 @@
} }
</script> </script>
<div class="flex items-center space-x-2 p-5 px-6 font-bold">
<div class="-mb-5 flex-col">
<div class="md:max-w-64 truncate text-base tracking-tight md:text-2xl lg:block">
{$t('application.secret')}
</div>
<span class="text-xs">{application.name} </span>
</div>
{#if application.gitSource?.htmlUrl && application.repository && application.branch}
<a
href="{application.gitSource.htmlUrl}/{application.repository}/tree/{application.branch}"
target="_blank"
class="w-10"
>
{#if application.gitSource?.type === 'gitlab'}
<svg viewBox="0 0 128 128" class="icons">
<path
fill="#FC6D26"
d="M126.615 72.31l-7.034-21.647L105.64 7.76c-.716-2.206-3.84-2.206-4.556 0l-13.94 42.903H40.856L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664 1.385 72.31a4.792 4.792 0 001.74 5.358L64 121.894l60.874-44.227a4.793 4.793 0 001.74-5.357"
/><path fill="#E24329" d="M64 121.894l23.144-71.23H40.856L64 121.893z" /><path
fill="#FC6D26"
d="M64 121.894l-23.144-71.23H8.42L64 121.893z"
/><path
fill="#FCA326"
d="M8.42 50.663L1.384 72.31a4.79 4.79 0 001.74 5.357L64 121.894 8.42 50.664z"
/><path
fill="#E24329"
d="M8.42 50.663h32.436L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664z"
/><path fill="#FC6D26" d="M64 121.894l23.144-71.23h32.437L64 121.893z" /><path
fill="#FCA326"
d="M119.58 50.663l7.035 21.647a4.79 4.79 0 01-1.74 5.357L64 121.894l55.58-71.23z"
/><path
fill="#E24329"
d="M119.58 50.663H87.145l13.94-42.902c.717-2.206 3.84-2.206 4.557 0l13.94 42.903z"
/>
</svg>
{:else if application.gitSource?.type === 'github'}
<svg viewBox="0 0 128 128" class="icons">
<g fill="#ffffff"
><path
fill-rule="evenodd"
clip-rule="evenodd"
d="M64 5.103c-33.347 0-60.388 27.035-60.388 60.388 0 26.682 17.303 49.317 41.297 57.303 3.017.56 4.125-1.31 4.125-2.905 0-1.44-.056-6.197-.082-11.243-16.8 3.653-20.345-7.125-20.345-7.125-2.747-6.98-6.705-8.836-6.705-8.836-5.48-3.748.413-3.67.413-3.67 6.063.425 9.257 6.223 9.257 6.223 5.386 9.23 14.127 6.562 17.573 5.02.542-3.903 2.107-6.568 3.834-8.076-13.413-1.525-27.514-6.704-27.514-29.843 0-6.593 2.36-11.98 6.223-16.21-.628-1.52-2.695-7.662.584-15.98 0 0 5.07-1.623 16.61 6.19C53.7 35 58.867 34.327 64 34.304c5.13.023 10.3.694 15.127 2.033 11.526-7.813 16.59-6.19 16.59-6.19 3.287 8.317 1.22 14.46.593 15.98 3.872 4.23 6.215 9.617 6.215 16.21 0 23.194-14.127 28.3-27.574 29.796 2.167 1.874 4.097 5.55 4.097 11.183 0 8.08-.07 14.583-.07 16.572 0 1.607 1.088 3.49 4.148 2.897 23.98-7.994 41.263-30.622 41.263-57.294C124.388 32.14 97.35 5.104 64 5.104z"
/><path
d="M26.484 91.806c-.133.3-.605.39-1.035.185-.44-.196-.685-.605-.543-.906.13-.31.603-.395 1.04-.188.44.197.69.61.537.91zm2.446 2.729c-.287.267-.85.143-1.232-.28-.396-.42-.47-.983-.177-1.254.298-.266.844-.14 1.24.28.394.426.472.984.17 1.255zM31.312 98.012c-.37.258-.976.017-1.35-.52-.37-.538-.37-1.183.01-1.44.373-.258.97-.025 1.35.507.368.545.368 1.19-.01 1.452zm3.261 3.361c-.33.365-1.036.267-1.552-.23-.527-.487-.674-1.18-.343-1.544.336-.366 1.045-.264 1.564.23.527.486.686 1.18.333 1.543zm4.5 1.951c-.147.473-.825.688-1.51.486-.683-.207-1.13-.76-.99-1.238.14-.477.823-.7 1.512-.485.683.206 1.13.756.988 1.237zm4.943.361c.017.498-.563.91-1.28.92-.723.017-1.308-.387-1.315-.877 0-.503.568-.91 1.29-.924.717-.013 1.306.387 1.306.88zm4.598-.782c.086.485-.413.984-1.126 1.117-.7.13-1.35-.172-1.44-.653-.086-.498.422-.997 1.122-1.126.714-.123 1.354.17 1.444.663zm0 0"
/></g
>
</svg>
{/if}
</a>
{/if}
</div>
<div class="mx-auto max-w-6xl px-6 pt-4"> <div class="mx-auto max-w-6xl px-6 pt-4">
<table class="mx-auto border-separate text-left"> <div class="overflow-x-auto">
<thead> <table class="mx-auto border-separate text-left">
<tr class="h-12"> <thead>
<th scope="col">{$t('forms.name')}</th> <tr class="h-12">
<th scope="col">{$t('forms.value')}</th> <th scope="col">{$t('forms.name')}</th>
<th scope="col" class="w-64 text-center" <th scope="col">{$t('forms.value')}</th>
>{$t('application.preview.need_during_buildtime')}</th <th scope="col" class="w-64 text-center"
> >{$t('application.preview.need_during_buildtime')}</th
<th scope="col" class="w-96 text-center">{$t('forms.action')}</th> >
</tr> <th scope="col" class="w-96 text-center">{$t('forms.action')}</th>
</thead> </tr>
<tbody> </thead>
{#each secrets as secret} <tbody>
{#key secret.id} {#each secrets as secret}
<tr> {#key secret.id}
<Secret <tr>
name={secret.name} <Secret
value={secret.value} name={secret.name}
isBuildSecret={secret.isBuildSecret} value={secret.value}
on:refresh={refreshSecrets} isBuildSecret={secret.isBuildSecret}
/> on:refresh={refreshSecrets}
</tr> />
{/key} </tr>
{/each} {/key}
<tr> {/each}
<Secret isNewSecret on:refresh={refreshSecrets} /> <tr>
</tr> <Secret isNewSecret on:refresh={refreshSecrets} />
</tbody> </tr>
</table> </tbody>
</table>
</div>
<h2 class="title my-6 font-bold">Paste .env file</h2> <h2 class="title my-6 font-bold">Paste .env file</h2>
<form on:submit|preventDefault={getValues} class="mb-12 w-full"> <form on:submit|preventDefault={getValues} class="mb-12 w-full">
<textarea bind:value={batchSecrets} class="mb-2 min-h-[200px] w-full" /> <textarea bind:value={batchSecrets} class="mb-2 min-h-[200px] w-full" />

View File

@@ -5,7 +5,6 @@
const response = await get(`/applications/${params.id}/storages`); const response = await get(`/applications/${params.id}/storages`);
return { return {
props: { props: {
application: stuff.application,
...response ...response
} }
}; };
@@ -19,13 +18,12 @@
</script> </script>
<script lang="ts"> <script lang="ts">
export let application: any;
export let persistentStorages: any; export let persistentStorages: any;
import { page } from '$app/stores'; import { page } from '$app/stores';
import Storage from './_Storage.svelte'; import Storage from './_Storage.svelte';
import { get } from '$lib/api'; import { get } from '$lib/api';
import SimpleExplainer from '$lib/components/SimpleExplainer.svelte';
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import Explainer from '$lib/components/Explainer.svelte';
const { id } = $page.params; const { id } = $page.params;
async function refreshStorage() { async function refreshStorage() {
@@ -34,66 +32,12 @@
} }
</script> </script>
<div class="flex items-center space-x-2 p-5 px-6 font-bold">
<div class="-mb-5 flex-col">
<div class="md:max-w-64 truncate text-base tracking-tight md:text-2xl lg:block">
Persistent Storage
</div>
<span class="text-xs">{application.name} </span>
</div>
{#if application.gitSource?.htmlUrl && application.repository && application.branch}
<a
href="{application.gitSource.htmlUrl}/{application.repository}/tree/{application.branch}"
target="_blank"
class="w-10"
>
{#if application.gitSource?.type === 'gitlab'}
<svg viewBox="0 0 128 128" class="icons">
<path
fill="#FC6D26"
d="M126.615 72.31l-7.034-21.647L105.64 7.76c-.716-2.206-3.84-2.206-4.556 0l-13.94 42.903H40.856L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664 1.385 72.31a4.792 4.792 0 001.74 5.358L64 121.894l60.874-44.227a4.793 4.793 0 001.74-5.357"
/><path fill="#E24329" d="M64 121.894l23.144-71.23H40.856L64 121.893z" /><path
fill="#FC6D26"
d="M64 121.894l-23.144-71.23H8.42L64 121.893z"
/><path
fill="#FCA326"
d="M8.42 50.663L1.384 72.31a4.79 4.79 0 001.74 5.357L64 121.894 8.42 50.664z"
/><path
fill="#E24329"
d="M8.42 50.663h32.436L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664z"
/><path fill="#FC6D26" d="M64 121.894l23.144-71.23h32.437L64 121.893z" /><path
fill="#FCA326"
d="M119.58 50.663l7.035 21.647a4.79 4.79 0 01-1.74 5.357L64 121.894l55.58-71.23z"
/><path
fill="#E24329"
d="M119.58 50.663H87.145l13.94-42.902c.717-2.206 3.84-2.206 4.557 0l13.94 42.903z"
/>
</svg>
{:else if application.gitSource?.type === 'github'}
<svg viewBox="0 0 128 128" class="icons">
<g fill="#ffffff"
><path
fill-rule="evenodd"
clip-rule="evenodd"
d="M64 5.103c-33.347 0-60.388 27.035-60.388 60.388 0 26.682 17.303 49.317 41.297 57.303 3.017.56 4.125-1.31 4.125-2.905 0-1.44-.056-6.197-.082-11.243-16.8 3.653-20.345-7.125-20.345-7.125-2.747-6.98-6.705-8.836-6.705-8.836-5.48-3.748.413-3.67.413-3.67 6.063.425 9.257 6.223 9.257 6.223 5.386 9.23 14.127 6.562 17.573 5.02.542-3.903 2.107-6.568 3.834-8.076-13.413-1.525-27.514-6.704-27.514-29.843 0-6.593 2.36-11.98 6.223-16.21-.628-1.52-2.695-7.662.584-15.98 0 0 5.07-1.623 16.61 6.19C53.7 35 58.867 34.327 64 34.304c5.13.023 10.3.694 15.127 2.033 11.526-7.813 16.59-6.19 16.59-6.19 3.287 8.317 1.22 14.46.593 15.98 3.872 4.23 6.215 9.617 6.215 16.21 0 23.194-14.127 28.3-27.574 29.796 2.167 1.874 4.097 5.55 4.097 11.183 0 8.08-.07 14.583-.07 16.572 0 1.607 1.088 3.49 4.148 2.897 23.98-7.994 41.263-30.622 41.263-57.294C124.388 32.14 97.35 5.104 64 5.104z"
/><path
d="M26.484 91.806c-.133.3-.605.39-1.035.185-.44-.196-.685-.605-.543-.906.13-.31.603-.395 1.04-.188.44.197.69.61.537.91zm2.446 2.729c-.287.267-.85.143-1.232-.28-.396-.42-.47-.983-.177-1.254.298-.266.844-.14 1.24.28.394.426.472.984.17 1.255zM31.312 98.012c-.37.258-.976.017-1.35-.52-.37-.538-.37-1.183.01-1.44.373-.258.97-.025 1.35.507.368.545.368 1.19-.01 1.452zm3.261 3.361c-.33.365-1.036.267-1.552-.23-.527-.487-.674-1.18-.343-1.544.336-.366 1.045-.264 1.564.23.527.486.686 1.18.333 1.543zm4.5 1.951c-.147.473-.825.688-1.51.486-.683-.207-1.13-.76-.99-1.238.14-.477.823-.7 1.512-.485.683.206 1.13.756.988 1.237zm4.943.361c.017.498-.563.91-1.28.92-.723.017-1.308-.387-1.315-.877 0-.503.568-.91 1.29-.924.717-.013 1.306.387 1.306.88zm4.598-.782c.086.485-.413.984-1.126 1.117-.7.13-1.35-.172-1.44-.653-.086-.498.422-.997 1.122-1.126.714-.123 1.354.17 1.444.663zm0 0"
/></g
>
</svg>
{/if}
</a>
{/if}
</div>
<div class="mx-auto max-w-6xl rounded-xl px-6 pt-4"> <div class="mx-auto max-w-6xl rounded-xl px-6 pt-4">
<div class="flex justify-center py-4 text-center">
<SimpleExplainer customClass="w-full" text={$t('application.storage.persistent_storage_explainer')} />
</div>
<table class="mx-auto border-separate text-left"> <table class="mx-auto border-separate text-left">
<thead> <thead>
<tr class="h-12"> <tr class="h-12">
<th scope="col">{$t('forms.path')}</th> <th scope="col">{$t('forms.path')} <Explainer explanation={$t('application.storage.persistent_storage_explainer')} /></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@@ -44,8 +44,8 @@
} }
</script> </script>
<div class="flex space-x-1 p-6 font-bold"> <nav class="header">
<div class="mr-4 text-2xl">{$t('index.applications')}</div> <h1 class="mr-4 text-2xl font-bold">{$t('index.applications')}</h1>
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<button on:click={newApplication} class="btn btn-square btn-sm bg-applications"> <button on:click={newApplication} class="btn btn-square btn-sm bg-applications">
<svg <svg
@@ -63,8 +63,9 @@
> >
</button> </button>
{/if} {/if}
</div> </nav>
<div class="flex-col justify-center mt-10 pb-12 sm:pb-16"> <br />
<div class="flex flex-col justify-center mt-10 pb-12 lg:pt-16 sm:pb-16">
{#if !applications || ownApplications.length === 0} {#if !applications || ownApplications.length === 0}
<div class="flex-col"> <div class="flex-col">
<div class="text-center text-xl font-bold">{$t('application.no_applications_found')}</div> <div class="text-center text-xl font-bold">{$t('application.no_applications_found')}</div>

View File

@@ -5,13 +5,11 @@
</script> </script>
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">CouchDB</div> <h1 class="title">CouchDB</h1>
</div> </div>
<div class="space-y-2 px-10"> <div class="space-y-2 lg:px-10 px-2">
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="defaultDatabase" class="text-base font-bold text-stone-100" <label for="defaultDatabase">{$t('database.default_database')}</label>
>{$t('database.default_database')}</label
>
<CopyPasswordField <CopyPasswordField
required required
readonly={database.defaultDatabase} readonly={database.defaultDatabase}
@@ -23,7 +21,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="dbUser" class="text-base font-bold text-stone-100">{$t('forms.user')}</label> <label for="dbUser">{$t('forms.user')}</label>
<CopyPasswordField <CopyPasswordField
readonly readonly
disabled disabled
@@ -34,9 +32,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="dbUserPassword" class="text-base font-bold text-stone-100" <label for="dbUserPassword">{$t('forms.password')}</label>
>{$t('forms.password')}</label
>
<CopyPasswordField <CopyPasswordField
readonly readonly
disabled disabled
@@ -48,7 +44,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="rootUser" class="text-base font-bold text-stone-100">{$t('forms.root_user')}</label> <label for="rootUser">{$t('forms.root_user')}</label>
<CopyPasswordField <CopyPasswordField
readonly readonly
disabled disabled
@@ -59,9 +55,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="rootUserPassword" class="text-base font-bold text-stone-100" <label for="rootUserPassword">{$t('forms.roots_password')}</label>
>{$t('forms.roots_password')}</label
>
<CopyPasswordField <CopyPasswordField
readonly readonly
disabled disabled

View File

@@ -107,10 +107,10 @@
} }
</script> </script>
<div class="mx-auto max-w-4xl px-6"> <div class="mx-auto max-w-6xl p-4">
<form on:submit|preventDefault={handleSubmit} class="py-4"> <form on:submit|preventDefault={handleSubmit} class="py-4">
<div class="flex space-x-1 pb-5"> <div class="flex space-x-1 pb-5 items-center">
<div class="title">{$t('general')}</div> <h1 class="title">{$t('general')}</h1>
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<button <button
type="submit" type="submit"
@@ -121,106 +121,94 @@
> >
{/if} {/if}
</div> </div>
<div class="grid gap-4 grid-cols-2 auto-rows-max lg:px-10 px-2">
<div class="grid grid-flow-row gap-2 px-10"> <label for="name">{$t('forms.name')}</label>
<div class="grid grid-cols-2 items-center"> <input
<label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label> class="w-full"
<input readonly={!$appSession.isAdmin}
readonly={!$appSession.isAdmin} name="name"
name="name" id="name"
id="name" bind:value={database.name}
bind:value={database.name} required
required />
/> <label for="destination">{$t('application.destination')}</label>
</div> {#if database.destinationDockerId}
<div class="grid grid-cols-2 items-center"> <div class="no-underline">
<label for="destination" class="text-base font-bold text-stone-100"
>{$t('application.destination')}</label
>
{#if database.destinationDockerId}
<div class="no-underline">
<input
value={database.destinationDocker.name}
id="destination"
disabled
readonly
class="bg-transparent "
/>
</div>
{/if}
</div>
<div class="grid grid-cols-2 items-center">
<label for="version" class="text-base font-bold text-stone-100">Version / Tag</label>
<a
href={$appSession.isAdmin && !$status.database.isRunning
? `/databases/${id}/configuration/version?from=/databases/${id}`
: ''}
class="no-underline"
>
<input <input
value={database.version} value={database.destinationDocker.name}
id="destination"
disabled
readonly readonly
disabled={$status.database.isRunning || $status.database.initialLoading} class="bg-transparent w-full"
class:cursor-pointer={!$status.database.isRunning} />
/></a
>
</div>
</div>
<div class="grid grid-flow-row gap-2 px-10 pt-2">
<div class="grid grid-cols-2 items-center">
<label for="host" class="text-base font-bold text-stone-100">{$t('forms.host')}</label>
<CopyPasswordField
placeholder={$t('forms.generated_automatically_after_start')}
isPasswordField={false}
readonly
disabled
id="host"
name="host"
value={database.id}
/>
</div>
<div class="grid grid-cols-2 items-center">
<label for="publicPort" class="text-base font-bold text-stone-100">{$t('forms.port')}</label
>
<CopyPasswordField
placeholder={$t('database.generated_automatically_after_set_to_public')}
id="publicPort"
readonly
disabled
name="publicPort"
value={publicLoading ? 'Loading...' : $status.database.isPublic ? database.publicPort : privatePort}
/>
</div>
</div>
<div class="grid grid-flow-row gap-2">
{#if database.type === 'mysql'}
<MySql bind:database />
{:else if database.type === 'postgresql'}
<PostgreSql bind:database />
{:else if database.type === 'mongodb'}
<MongoDb bind:database />
{:else if database.type === 'mariadb'}
<MariaDb bind:database />
{:else if database.type === 'redis'}
<Redis bind:database />
{:else if database.type === 'couchdb'}
<CouchDb {database} />
{:else if database.type === 'edgedb'}
<EdgeDB {database} />
{/if}
<div class="grid grid-cols-2 items-center px-10 pb-8">
<div>
<label for="url" class="text-base font-bold text-stone-100"
>{$t('database.connection_string')}
{#if !$status.database.isPublic && database.destinationDocker.remoteEngine}
<Explainer
explanation="You can only access the database with this URL if your application is deployed to the same Destination."
/>
{/if}</label
>
</div> </div>
{/if}
<label for="version">Version / Tag</label>
<a
href={$appSession.isAdmin && !$status.database.isRunning
? `/databases/${id}/configuration/version?from=/databases/${id}`
: ''}
class="no-underline"
>
<input
class="w-full"
value={database.version}
readonly
disabled={$status.database.isRunning || $status.database.initialLoading}
class:cursor-pointer={!$status.database.isRunning}
/></a
>
<label for="host">{$t('forms.host')}</label>
<CopyPasswordField
placeholder={$t('forms.generated_automatically_after_start')}
isPasswordField={false}
readonly
disabled
id="host"
name="host"
value={database.id}
/>
<label for="publicPort">{$t('forms.port')}</label>
<CopyPasswordField
placeholder={$t('database.generated_automatically_after_set_to_public')}
id="publicPort"
readonly
disabled
name="publicPort"
value={publicLoading
? 'Loading...'
: $status.database.isPublic
? database.publicPort
: privatePort}
/>
</div>
{#if database.type === 'mysql'}
<MySql bind:database />
{:else if database.type === 'postgresql'}
<PostgreSql bind:database />
{:else if database.type === 'mongodb'}
<MongoDb bind:database />
{:else if database.type === 'mariadb'}
<MariaDb bind:database />
{:else if database.type === 'redis'}
<Redis bind:database />
{:else if database.type === 'couchdb'}
<CouchDb {database} />
{:else if database.type === 'edgedb'}
<EdgeDB {database} />
{/if}
<div class="flex flex-col space-y-2 mt-5">
<div>
<label class="px-2" for="url"
>{$t('database.connection_string')}
{#if !$status.database.isPublic && database.destinationDocker.remoteEngine}
<Explainer
explanation="You can only access the database with this URL if your application is deployed to the same Destination."
/>
{/if}</label
>
</div>
<div class="lg:px-10 px-2">
<CopyPasswordField <CopyPasswordField
textarea={true} textarea={true}
placeholder={$t('forms.generated_automatically_after_start')} placeholder={$t('forms.generated_automatically_after_start')}
@@ -235,31 +223,27 @@
</div> </div>
</form> </form>
<div class="flex space-x-1 pb-5 font-bold"> <div class="flex space-x-1 pb-5 font-bold">
<div class="title">{$t('application.features')}</div> <h1 class="title">{$t('application.features')}</h1>
</div> </div>
<div class="px-10 pb-10"> <div class="grid gap-4 grid-cols-2 auto-rows-max lg:px-10 px-2">
<div class="grid grid-cols-2 items-center"> <Setting
<Setting id="isPublic"
id="isPublic" loading={publicLoading}
loading={publicLoading} bind:setting={$status.database.isPublic}
bind:setting={$status.database.isPublic} on:click={() => changeSettings('isPublic')}
on:click={() => changeSettings('isPublic')} title={$t('database.set_public')}
title={$t('database.set_public')} description={$t('database.warning_database_public')}
description={$t('database.warning_database_public')} disabled={!$status.database.isRunning}
disabled={!$status.database.isRunning} />
/>
</div>
{#if database.type === 'redis'} {#if database.type === 'redis'}
<div class="grid grid-cols-2 items-center"> <Setting
<Setting id="appendOnly"
id="appendOnly" loading={publicLoading}
loading={publicLoading} bind:setting={appendOnly}
bind:setting={appendOnly} on:click={() => changeSettings('appendOnly')}
on:click={() => changeSettings('appendOnly')} title={$t('database.change_append_only_mode')}
title={$t('database.change_append_only_mode')} description={$t('database.warning_append_only')}
description={$t('database.warning_append_only')} />
/>
</div>
{/if} {/if}
</div> </div>
</div> </div>

View File

@@ -9,11 +9,9 @@
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">EdgeDB</div> <div class="title">EdgeDB</div>
</div> </div>
<div class="space-y-2 px-10"> <div class="space-y-2 lg:px-10 px-2">
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="defaultDatabase" class="text-base font-bold text-stone-100" <label for="defaultDatabase">{$t('database.default_database')}</label>
>{$t('database.default_database')}</label
>
<CopyPasswordField <CopyPasswordField
required required
readonly={database.defaultDatabase} readonly={database.defaultDatabase}
@@ -25,7 +23,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="rootUser" class="text-base font-bold text-stone-100">{$t('forms.root_user')}</label> <label for="rootUser">{$t('forms.root_user')}</label>
<CopyPasswordField <CopyPasswordField
readonly readonly
disabled disabled
@@ -36,7 +34,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="rootUser" class="text-base font-bold text-stone-100" <label for="rootUser"
>Root Password <Explainer >Root Password <Explainer
explanation="Could be changed while the database is running." explanation="Could be changed while the database is running."
/></label /></label

View File

@@ -7,11 +7,11 @@
</script> </script>
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">MariaDB</div> <h1 class="title">MariaDB</h1>
</div> </div>
<div class="space-y-2 px-10"> <div class="space-y-2 lg:px-10 px-2">
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="defaultDatabase" class="text-base font-bold text-stone-100" <label for="defaultDatabase"
>{$t('database.default_database')}</label >{$t('database.default_database')}</label
> >
<CopyPasswordField <CopyPasswordField
@@ -25,7 +25,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="dbUser" class="text-base font-bold text-stone-100">{$t('forms.user')}</label> <label for="dbUser" >{$t('forms.user')}</label>
<CopyPasswordField <CopyPasswordField
readonly readonly
disabled disabled
@@ -36,7 +36,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="dbUserPassword" class="text-base font-bold text-stone-100" <label for="dbUserPassword"
>{$t('forms.password')} >{$t('forms.password')}
<Explainer explanation="Could be changed while the database is running." /></label <Explainer explanation="Could be changed while the database is running." /></label
> >
@@ -51,7 +51,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="rootUser" class="text-base font-bold text-stone-100">{$t('forms.root_user')}</label> <label for="rootUser" >{$t('forms.root_user')}</label>
<CopyPasswordField <CopyPasswordField
readonly readonly
disabled disabled
@@ -62,8 +62,9 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="rootUserPassword" class="text-base font-bold text-stone-100" <label for="rootUserPassword"
>{$t('forms.roots_password')} <Explainer explanation="Could be changed while the database is running." /></label >{$t('forms.roots_password')}
<Explainer explanation="Could be changed while the database is running." /></label
> >
<CopyPasswordField <CopyPasswordField
disabled={!$status.database.isRunning} disabled={!$status.database.isRunning}

View File

@@ -7,11 +7,11 @@
</script> </script>
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">MongoDB</div> <h1 class="title">MongoDB</h1>
</div> </div>
<div class="space-y-2 px-10"> <div class="space-y-2 lg:px-10 px-2">
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="rootUser" class="text-base font-bold text-stone-100">{$t('forms.root_user')}</label> <label for="rootUser">{$t('forms.root_user')}</label>
<CopyPasswordField <CopyPasswordField
placeholder={$t('forms.generated_automatically_after_start')} placeholder={$t('forms.generated_automatically_after_start')}
id="rootUser" id="rootUser"
@@ -22,7 +22,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="rootUserPassword" class="text-base font-bold text-stone-100" <label for="rootUserPassword"
>{$t('forms.roots_password')} >{$t('forms.roots_password')}
<Explainer explanation="Could be changed while the database is running." /></label <Explainer explanation="Could be changed while the database is running." /></label
> >

View File

@@ -7,13 +7,11 @@
</script> </script>
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">MySQL</div> <h1 class="title">MySQL</h1>
</div> </div>
<div class="space-y-2 px-10"> <div class="space-y-2 lg:px-10 px-2">
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="defaultDatabase" class="text-base font-bold text-stone-100" <label for="defaultDatabase">{$t('database.default_database')}</label>
>{$t('database.default_database')}</label
>
<CopyPasswordField <CopyPasswordField
required required
readonly={database.defaultDatabase} readonly={database.defaultDatabase}
@@ -25,7 +23,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="dbUser" class="text-base font-bold text-stone-100">{$t('forms.user')}</label> <label for="dbUser">{$t('forms.user')}</label>
<CopyPasswordField <CopyPasswordField
readonly readonly
disabled disabled
@@ -36,7 +34,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="dbUserPassword" class="text-base font-bold text-stone-100" <label for="dbUserPassword"
>{$t('forms.password')} >{$t('forms.password')}
<Explainer explanation="Could be changed while the database is running." /></label <Explainer explanation="Could be changed while the database is running." /></label
> >
@@ -51,7 +49,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="rootUser" class="text-base font-bold text-stone-100">{$t('forms.root_user')}</label> <label for="rootUser">{$t('forms.root_user')}</label>
<CopyPasswordField <CopyPasswordField
readonly readonly
disabled disabled
@@ -62,7 +60,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="rootUserPassword" class="text-base font-bold text-stone-100" <label for="rootUserPassword"
>{$t('forms.roots_password')} >{$t('forms.roots_password')}
<Explainer explanation="Could be changed while the database is running." /></label <Explainer explanation="Could be changed while the database is running." /></label
> >

View File

@@ -7,13 +7,11 @@
</script> </script>
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">PostgreSQL</div> <h1 class="title">PostgreSQL</h1>
</div> </div>
<div class="space-y-2 px-10"> <div class="space-y-2 lg:px-10 px-2">
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="defaultDatabase" class="text-base font-bold text-stone-100" <label for="defaultDatabase">{$t('database.default_database')}</label>
>{$t('database.default_database')}</label
>
<CopyPasswordField <CopyPasswordField
required required
readonly={database.defaultDatabase} readonly={database.defaultDatabase}
@@ -25,7 +23,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="rootUser" class="text-base font-bold text-stone-100" <label for="rootUser"
>Postgres User Password <Explainer >Postgres User Password <Explainer
explanation="Could be changed while the database is running." explanation="Could be changed while the database is running."
/></label /></label
@@ -41,7 +39,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="dbUser" class="text-base font-bold text-stone-100">{$t('forms.user')}</label> <label for="dbUser">{$t('forms.user')}</label>
<CopyPasswordField <CopyPasswordField
readonly readonly
disabled disabled
@@ -52,7 +50,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="dbUserPassword" class="text-base font-bold text-stone-100" <label for="dbUserPassword"
>{$t('forms.password')} >{$t('forms.password')}
<Explainer explanation="Could be changed while the database is running." /></label <Explainer explanation="Could be changed while the database is running." /></label
> >

View File

@@ -7,11 +7,11 @@
</script> </script>
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">Redis</div> <h1 class="title">Redis</h1>
</div> </div>
<div class="space-y-2 px-10"> <div class="space-y-2 lg:px-10 px-2">
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="dbUserPassword" class="text-base font-bold text-stone-100" <label for="dbUserPassword"
>{$t('forms.password')} >{$t('forms.password')}
<Explainer explanation="Could be changed while the database is running." /></label <Explainer explanation="Could be changed while the database is running." /></label
> >

View File

@@ -62,6 +62,7 @@
import DeleteIcon from '$lib/components/DeleteIcon.svelte'; import DeleteIcon from '$lib/components/DeleteIcon.svelte';
import { onDestroy, onMount } from 'svelte'; import { onDestroy, onMount } from 'svelte';
import Tooltip from '$lib/components/Tooltip.svelte'; import Tooltip from '$lib/components/Tooltip.svelte';
import DatabaseLinks from './_DatabaseLinks.svelte';
const { id } = $page.params; const { id } = $page.params;
$status.database.isPublic = database.settings.isPublic || false; $status.database.isPublic = database.settings.isPublic || false;
@@ -149,104 +150,123 @@
</script> </script>
{#if id !== 'new'} {#if id !== 'new'}
<nav class="nav-side"> <nav class="header lg:flex-row flex-col-reverse">
{#if database.type && database.destinationDockerId && database.version} <div class="flex flex-row space-x-2 font-bold pt-10 lg:pt-0">
{#if $status.database.isExited} <div class="flex flex-col items-center justify-center">
<a <div class="title">
id="exited" {#if $page.url.pathname === `/databases/${id}`}
href={!$status.database.isRunning ? `/databases/${id}/logs` : null} Configurations
class="icons bg-transparent text-sm flex items-center text-red-500 tooltip-error" {:else if $page.url.pathname === `/databases/${id}/logs`}
sveltekit:prefetch Database Logs
> {:else if $page.url.pathname === `/databases/${id}/configuration/type`}
<svg Select a Database Type
xmlns="http://www.w3.org/2000/svg" {:else if $page.url.pathname === `/databases/${id}/configuration/version`}
class="w-6 h-6" Select a Database Version
viewBox="0 0 24 24" {:else if $page.url.pathname === `/databases/${id}/configuration/destination`}
stroke-width="1.5" Select a Destination
stroke="currentcolor" {/if}
fill="none" </div>
stroke-linecap="round" </div>
stroke-linejoin="round" <DatabaseLinks {database} />
</div>
<div class="lg:block hidden flex-1" />
<div class="flex flex-row flex-wrap space-x-3 justify-center lg:justify-start lg:py-0">
{#if database.type && database.destinationDockerId && database.version}
{#if $status.database.isExited}
<a
id="exited"
href={!$status.database.isRunning ? `/databases/${id}/logs` : null}
class="icons bg-transparent text-red-500 tooltip-error"
sveltekit:prefetch
> >
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> <svg
<path xmlns="http://www.w3.org/2000/svg"
d="M8.7 3h6.6c.3 0 .5 .1 .7 .3l4.7 4.7c.2 .2 .3 .4 .3 .7v6.6c0 .3 -.1 .5 -.3 .7l-4.7 4.7c-.2 .2 -.4 .3 -.7 .3h-6.6c-.3 0 -.5 -.1 -.7 -.3l-4.7 -4.7c-.2 -.2 -.3 -.4 -.3 -.7v-6.6c0 -.3 .1 -.5 .3 -.7l4.7 -4.7c.2 -.2 .4 -.3 .7 -.3z" class="w-6 h-6"
/> viewBox="0 0 24 24"
<line x1="12" y1="8" x2="12" y2="12" /> stroke-width="1.5"
<line x1="12" y1="16" x2="12.01" y2="16" /> stroke="currentcolor"
</svg> fill="none"
</a> stroke-linecap="round"
<Tooltip triggeredBy="#exited">{'Service exited with an error!'}</Tooltip> stroke-linejoin="round"
{/if} >
{#if $status.database.initialLoading} <path stroke="none" d="M0 0h24v24H0z" fill="none" />
<button <path
class="icons flex animate-spin items-center space-x-2 bg-transparent text-sm duration-500 ease-in-out hover:bg-transparent" d="M8.7 3h6.6c.3 0 .5 .1 .7 .3l4.7 4.7c.2 .2 .3 .4 .3 .7v6.6c0 .3 -.1 .5 -.3 .7l-4.7 4.7c-.2 .2 -.4 .3 -.7 .3h-6.6c-.3 0 -.5 -.1 -.7 -.3l-4.7 -4.7c-.2 -.2 -.3 -.4 -.3 -.7v-6.6c0 -.3 .1 -.5 .3 -.7l4.7 -4.7c.2 -.2 .4 -.3 .7 -.3z"
> />
<svg <line x1="12" y1="8" x2="12" y2="12" />
xmlns="http://www.w3.org/2000/svg" <line x1="12" y1="16" x2="12.01" y2="16" />
class="h-6 w-6" </svg>
viewBox="0 0 24 24" </a>
stroke-width="1.5" <Tooltip triggeredBy="#exited">{'Service exited with an error!'}</Tooltip>
stroke="currentColor" {/if}
fill="none" {#if $status.database.initialLoading}
stroke-linecap="round" <button class="icons flex animate-spin duration-500 ease-in-out">
stroke-linejoin="round" <svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-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 4.55a8 8 0 0 1 6 14.9m0 -4.45v5h5" />
<line x1="5.63" y1="7.16" x2="5.63" y2="7.17" />
<line x1="4.06" y1="11" x2="4.06" y2="11.01" />
<line x1="4.63" y1="15.1" x2="4.63" y2="15.11" />
<line x1="7.16" y1="18.37" x2="7.16" y2="18.38" />
<line x1="11" y1="19.94" x2="11" y2="19.95" />
</svg>
</button>
{:else if $status.database.isRunning}
<button
id="stop"
on:click={stopDatabase}
type="submit"
disabled={!$appSession.isAdmin}
class="icons bg-transparent text-red-500"
> >
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> <svg
<path d="M9 4.55a8 8 0 0 1 6 14.9m0 -4.45v5h5" /> xmlns="http://www.w3.org/2000/svg"
<line x1="5.63" y1="7.16" x2="5.63" y2="7.17" /> class="w-6 h-6"
<line x1="4.06" y1="11" x2="4.06" y2="11.01" /> viewBox="0 0 24 24"
<line x1="4.63" y1="15.1" x2="4.63" y2="15.11" /> stroke-width="1.5"
<line x1="7.16" y1="18.37" x2="7.16" y2="18.38" /> stroke="currentColor"
<line x1="11" y1="19.94" x2="11" y2="19.95" /> fill="none"
</svg> stroke-linecap="round"
</button> stroke-linejoin="round"
{:else if $status.database.isRunning} >
<button <path stroke="none" d="M0 0h24v24H0z" fill="none" />
id="stop" <rect x="6" y="5" width="4" height="14" rx="1" />
on:click={stopDatabase} <rect x="14" y="5" width="4" height="14" rx="1" />
type="submit" </svg>
disabled={!$appSession.isAdmin} </button>
class="icons bg-transparent text-sm flex items-center space-x-2 text-red-500" <Tooltip triggeredBy="#stop">{'Stop'}</Tooltip>
> {:else}
<svg <button
xmlns="http://www.w3.org/2000/svg" id="start"
class="w-6 h-6" on:click={startDatabase}
viewBox="0 0 24 24" type="submit"
stroke-width="1.5" disabled={!$appSession.isAdmin}
stroke="currentColor" class="icons bg-transparent text-sm flex items-center space-x-2 text-green-500"
fill="none" ><svg
stroke-linecap="round" xmlns="http://www.w3.org/2000/svg"
stroke-linejoin="round" class="w-6 h-6"
> viewBox="0 0 24 24"
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> stroke-width="1.5"
<rect x="6" y="5" width="4" height="14" rx="1" /> stroke="currentColor"
<rect x="14" y="5" width="4" height="14" rx="1" /> fill="none"
</svg> stroke-linecap="round"
</button> stroke-linejoin="round"
<Tooltip triggeredBy="#stop">{'Stop'}</Tooltip> >
{:else} <path stroke="none" d="M0 0h24v24H0z" fill="none" />
<button <path d="M7 4v16l13 -8z" />
id="start" </svg>
on:click={startDatabase} </button>
type="submit" <Tooltip triggeredBy="#start">{'Start'}</Tooltip>
disabled={!$appSession.isAdmin} {/if}
class="icons bg-transparent text-sm flex items-center space-x-2 text-green-500"
><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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M7 4v16l13 -8z" />
</svg>
</button>
<Tooltip triggeredBy="#start">{'Start'}</Tooltip>
{/if} {/if}
<div class="border border-stone-700 h-8" /> <div class="border border-stone-700 h-8" />
<a <a
@@ -282,34 +302,6 @@
></a ></a
> >
<Tooltip triggeredBy="#configuration">{'Configuration'}</Tooltip> <Tooltip triggeredBy="#configuration">{'Configuration'}</Tooltip>
<a
href="/databases/{id}/secrets"
sveltekit:prefetch
class="hover:text-pink-500 rounded"
class:text-pink-500={$page.url.pathname === `/databases/${id}/secrets`}
class:bg-coolgray-500={$page.url.pathname === `/databases/${id}/secrets`}
>
<button id="secrets" disabled={$isDeploymentEnabled} class="icons bg-transparent text-sm ">
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path
d="M12 3a12 12 0 0 0 8.5 3a12 12 0 0 1 -8.5 15a12 12 0 0 1 -8.5 -15a12 12 0 0 0 8.5 -3"
/>
<circle cx="12" cy="11" r="1" />
<line x1="12" y1="12" x2="12" y2="14.5" />
</svg></button
></a
>
<Tooltip triggeredBy="#secrets">Secrets</Tooltip>
<div class="border border-stone-700 h-8" /> <div class="border border-stone-700 h-8" />
<a <a
id="databaselogs" id="databaselogs"
@@ -340,29 +332,28 @@
></a ></a
> >
<Tooltip triggeredBy="#databaselogs">{'Logs'}</Tooltip> <Tooltip triggeredBy="#databaselogs">{'Logs'}</Tooltip>
{/if} {#if forceDelete}
<button
on:click={() => deleteDatabase(true)}
type="submit"
disabled={!$appSession.isAdmin}
class:hover:text-red-500={$appSession.isAdmin}
class="icons bg-transparent text-sm"
>
Force Delete</button
>{:else}
<button
id="delete"
on:click={() => deleteDatabase(false)}
type="submit"
disabled={!$appSession.isAdmin}
class:hover:text-red-500={$appSession.isAdmin}
class="icons bg-transparent text-sm"><DeleteIcon /></button
>
{/if}
{#if forceDelete} <Tooltip triggeredBy="#delete" placement="left">Delete</Tooltip>
<button </div>
on:click={() => deleteDatabase(true)}
type="submit"
disabled={!$appSession.isAdmin}
class:hover:text-red-500={$appSession.isAdmin}
class="icons bg-transparent text-sm"
>
Force Delete</button
>{:else}
<button
id="delete"
on:click={() => deleteDatabase(false)}
type="submit"
disabled={!$appSession.isAdmin}
class:hover:text-red-500={$appSession.isAdmin}
class="icons bg-transparent text-sm"><DeleteIcon /></button
>
{/if}
<Tooltip triggeredBy="#delete">{'Delete'}</Tooltip>
</nav> </nav>
{/if} {/if}
<slot /> <slot />

View File

@@ -53,11 +53,6 @@
}); });
</script> </script>
<div class="flex space-x-1 p-6 font-bold">
<div class="mr-4 text-2xl tracking-tight">
{$t('application.configuration.configure_destination')}
</div>
</div>
<div class="flex justify-center"> <div class="flex justify-center">
{#if !destinations || destinations.length === 0} {#if !destinations || destinations.length === 0}
<div class="flex-col"> <div class="flex-col">

View File

@@ -47,10 +47,6 @@
} }
</script> </script>
<div class="flex space-x-1 p-6 font-bold">
<div class="mr-4 text-2xl tracking-tight">{$t('database.select_database_type')}</div>
</div>
<div class="flex flex-wrap justify-center"> <div class="flex flex-wrap justify-center">
{#each types as type} {#each types as type}
<div class="p-2"> <div class="p-2">

View File

@@ -46,9 +46,6 @@
} }
</script> </script>
<div class="flex space-x-1 p-6 font-bold">
<div class="mr-4 text-2xl tracking-tight">{$t('database.select_database_version')}</div>
</div>
{#if from} {#if from}
<div class="pb-10 text-center"> <div class="pb-10 text-center">
Warning: you are about to change the version of this database.<br />This could cause problem Warning: you are about to change the version of this database.<br />This could cause problem

View File

@@ -48,33 +48,24 @@
}); });
</script> </script>
<div class="flex h-20 items-center space-x-2 p-5 px-6 font-bold"> {#if $status.database.isRunning}
<div class="-mb-5 flex-col"> <div class="mx-auto max-w-6xl p-5">
<div class="md:max-w-64 truncate text-base tracking-tight md:text-2xl lg:block"> <div class="text-center">
Configuration <div class="stat w-64">
</div> <div class="stat-title">Used Memory / Memory Limit</div>
<span class="text-xs">{database.name}</span> <div class="stat-value text-xl">{usage?.MemUsage}</div>
</div> </div>
<DatabaseLinks {database} />
</div>
<div class="mx-auto max-w-4xl px-6 py-4"> <div class="stat w-64">
<div class="text-2xl font-bold">Database Usage</div> <div class="stat-title">Used CPU</div>
<div class="text-center"> <div class="stat-value text-xl">{usage?.CPUPerc}</div>
<div class="stat w-64"> </div>
<div class="stat-title">Used Memory / Memory Limit</div>
<div class="stat-value text-xl">{usage?.MemUsage}</div>
</div>
<div class="stat w-64"> <div class="stat w-64">
<div class="stat-title">Used CPU</div> <div class="stat-title">Network IO</div>
<div class="stat-value text-xl">{usage?.CPUPerc}</div> <div class="stat-value text-xl">{usage?.NetIO}</div>
</div> </div>
<div class="stat w-64">
<div class="stat-title">Network IO</div>
<div class="stat-value text-xl">{usage?.NetIO}</div>
</div> </div>
</div> </div>
</div> {/if}
<Databases bind:database {privatePort} /> <Databases bind:database {privatePort} />

View File

@@ -91,14 +91,6 @@
} }
</script> </script>
<div class="flex h-20 items-center space-x-2 p-5 px-6 font-bold">
<div class="-mb-5 flex-col">
<div class="md:max-w-64 truncate text-base tracking-tight md:text-2xl lg:block">
Database Logs
</div>
<span class="text-xs">{database.name}</span>
</div>
</div>
<div class="flex flex-row justify-center space-x-2 px-10 pt-6"> <div class="flex flex-row justify-center space-x-2 px-10 pt-6">
{#if logs.length === 0} {#if logs.length === 0}
<div class="text-xl font-bold tracking-tighter">{$t('application.build.waiting_logs')}</div> <div class="text-xl font-bold tracking-tighter">{$t('application.build.waiting_logs')}</div>
@@ -134,7 +126,12 @@
</button> </button>
<Tooltip triggeredBy="#follow">Follow Logs</Tooltip> <Tooltip triggeredBy="#follow">Follow Logs</Tooltip>
</div> </div>
<div <div class="font-mono w-full rounder bg-coolgray-200 p-5 overflow-x-auto overflox-y-auto max-h-[80vh] rounded-md mb-20 flex flex-col whitespace-nowrap -mt-12 scrollbar-thumb-coollabs scrollbar-track-coolgray-200 scrollbar-w-1">
{#each logs as log}
<p>{log + '\n'}</p>
{/each}
</div>
<!-- <div
class="font-mono w-full leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12 overflow-y-scroll scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200" class="font-mono w-full leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12 overflow-y-scroll scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200"
bind:this={logsEl} bind:this={logsEl}
on:scroll={detect} on:scroll={detect}
@@ -144,7 +141,7 @@
{log + '\n'} {log + '\n'}
{/each} {/each}
</div> </div>
</div> </div> -->
</div> </div>
{/if} {/if}
</div> </div>

View File

@@ -42,8 +42,8 @@
}); });
</script> </script>
<div class="flex space-x-1 p-6 font-bold"> <nav class="header">
<div class="mr-4 text-2xl tracking-tight">{$t('index.databases')}</div> <h1 class="mr-4 text-2xl font-bold">{$t('index.databases')}</h1>
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<button on:click={newDatabase} class="btn btn-square btn-sm bg-databases"> <button on:click={newDatabase} class="btn btn-square btn-sm bg-databases">
<svg <svg
@@ -61,9 +61,9 @@
> >
</button> </button>
{/if} {/if}
</div> </nav>
<br />
<div class="flex-col justify-center mt-10 pb-12 sm:pb-16"> <div class="flex-col justify-center mt-10 pb-12 sm:pb-16 lg:pt-16">
{#if !databases || ownDatabases.length === 0} {#if !databases || ownDatabases.length === 0}
<div class="flex-col"> <div class="flex-col">
<div class="text-center text-xl font-bold">{$t('database.no_databases_found')}</div> <div class="text-center text-xl font-bold">{$t('database.no_databases_found')}</div>

View File

@@ -16,7 +16,7 @@
</div> </div>
</div> </div>
<div class="mx-auto max-w-4xl px-6"> <div class="mx-auto max-w-6xl px-6">
{#if destination.remoteEngine} {#if destination.remoteEngine}
<RemoteDocker bind:destination {settings} {state} /> <RemoteDocker bind:destination {settings} {state} />
{:else} {:else}

View File

@@ -141,40 +141,37 @@
} }
</script> </script>
<form on:submit|preventDefault={handleSubmit} class="grid grid-flow-row gap-2 py-4"> <form on:submit|preventDefault={handleSubmit} class="py-4">
<div class="flex md:flex-row space-y-2 md:space-y-0 space-x-0 md:space-x-2 flex-col pb-5"> <div class="grid gap-4 grid-cols-2 grid-rows-1">
<div class="title">{$t('forms.configuration')}</div> <button
{#if $appSession.isAdmin} type="submit"
<button class="btn btn-sm w-full"
type="submit" class:bg-destinations={!loading.save}
class="btn btn-sm" class:loading={loading.save}
class:bg-destinations={!loading.save} disabled={loading.save}
class:loading={loading.save} >{$t('forms.save')}
disabled={loading.save} </button>
>{$t('forms.save')} <button
</button> class="btn btn-sm w-full"
<button class:loading={loading.restart}
class="btn btn-sm" class:bg-error={!loading.restart}
class:loading={loading.restart} disabled={loading.restart}
class:bg-error={!loading.restart} on:click|preventDefault={forceRestartProxy}>{$t('destination.force_restart_proxy')}</button
disabled={loading.restart} >
on:click|preventDefault={forceRestartProxy}>{$t('destination.force_restart_proxy')}</button
>
{/if}
</div> </div>
<div class="grid lg:grid-cols-2 items-center px-10 "> <div class="grid gap-4 grid-cols-2 auto-rows-max mt-10 items-center">
<label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label> <label for="name" class="text-base font-bold text-stone-100 w-full">{$t('forms.name')}</label>
<input <input
class="w-full"
name="name" name="name"
placeholder={$t('forms.name')} placeholder={$t('forms.name')}
disabled={!$appSession.isAdmin} disabled={!$appSession.isAdmin}
readonly={!$appSession.isAdmin} readonly={!$appSession.isAdmin}
bind:value={destination.name} bind:value={destination.name}
/> />
</div> <label for="engine" class="text-base font-bold text-stone-100 w-full"
>{$t('forms.engine')}</label
<div class="grid lg:grid-cols-2 items-center px-10"> >
<label for="engine" class="text-base font-bold text-stone-100">{$t('forms.engine')}</label>
<CopyPasswordField <CopyPasswordField
id="engine" id="engine"
readonly readonly
@@ -183,8 +180,6 @@
placeholder="{$t('forms.eg')}: /var/run/docker.sock" placeholder="{$t('forms.eg')}: /var/run/docker.sock"
value={destination.engine} value={destination.engine}
/> />
</div>
<div class="grid lg:grid-cols-2 items-center px-10">
<label for="network" class="text-base font-bold text-stone-100">{$t('forms.network')}</label> <label for="network" class="text-base font-bold text-stone-100">{$t('forms.network')}</label>
<CopyPasswordField <CopyPasswordField
id="network" id="network"
@@ -194,9 +189,7 @@
placeholder="{$t('forms.default')}: coolify" placeholder="{$t('forms.default')}: coolify"
value={destination.network} value={destination.network}
/> />
</div> {#if $appSession.teamId === '0'}
{#if $appSession.teamId === '0'}
<div class="grid lg:grid-cols-2 items-center px-10">
<Setting <Setting
id="changeProxySetting" id="changeProxySetting"
loading={loading.proxy} loading={loading.proxy}
@@ -210,6 +203,6 @@
: '' : ''
}`} }`}
/> />
</div> {/if}
{/if} </div>
</form> </form>

View File

@@ -31,9 +31,9 @@
<div class="flex justify-center px-6 pb-8"> <div class="flex justify-center px-6 pb-8">
<form on:submit|preventDefault={handleSubmit} class="grid grid-flow-row gap-2 py-4"> <form on:submit|preventDefault={handleSubmit} class="grid grid-flow-row gap-2 py-4">
<div class="flex items-center space-x-2 pb-5"> <div class="flex items-start lg:items-center space-x-0 lg:space-x-4 pb-5 flex-col space-y-4 lg:space-y-0">
<div class="title font-bold">{$t('forms.configuration')}</div> <div class="title font-bold">{$t('forms.configuration')}</div>
<button type="submit" class="btn btn-sm bg-destinations" class:loading disabled={loading} <button type="submit" class="btn btn-sm bg-destinations w-full lg:w-fit" class:loading disabled={loading}
>{loading >{loading
? payload.isCoolifyProxyUsed ? payload.isCoolifyProxyUsed
? $t('destination.new.saving_and_configuring_proxy') ? $t('destination.new.saving_and_configuring_proxy')
@@ -41,12 +41,12 @@
: $t('forms.save')}</button : $t('forms.save')}</button
> >
</div> </div>
<div class="mt-2 grid grid-cols-2 items-center px-10"> <div class="mt-2 grid grid-cols-2 items-center lg:pl-10">
<label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label> <label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label>
<input required name="name" placeholder={$t('forms.name')} bind:value={payload.name} /> <input required name="name" placeholder={$t('forms.name')} bind:value={payload.name} />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:pl-10">
<label for="engine" class="text-base font-bold text-stone-100">{$t('forms.engine')}</label> <label for="engine" class="text-base font-bold text-stone-100">{$t('forms.engine')}</label>
<input <input
required required
@@ -55,7 +55,7 @@
bind:value={payload.engine} bind:value={payload.engine}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:pl-10">
<label for="network" class="text-base font-bold text-stone-100">{$t('forms.network')}</label> <label for="network" class="text-base font-bold text-stone-100">{$t('forms.network')}</label>
<input <input
required required
@@ -65,7 +65,7 @@
/> />
</div> </div>
{#if $appSession.teamId === '0'} {#if $appSession.teamId === '0'}
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:pl-10">
<Setting <Setting
id="changeProxySetting" id="changeProxySetting"
bind:setting={payload.isCoolifyProxyUsed} bind:setting={payload.isCoolifyProxyUsed}

View File

@@ -38,9 +38,9 @@
</div> </div>
<div class="flex justify-center px-6 pb-8"> <div class="flex justify-center px-6 pb-8">
<form on:submit|preventDefault={handleSubmit} class="grid grid-flow-row gap-2 py-4"> <form on:submit|preventDefault={handleSubmit} class="grid grid-flow-row gap-2 py-4">
<div class="flex items-center space-x-2 pb-5"> <div class="flex items-start lg:items-center space-x-0 lg:space-x-4 pb-5 flex-col lg:flex-row space-y-4 lg:space-y-0">
<div class="title font-bold">{$t('forms.configuration')}</div> <div class="title font-bold">{$t('forms.configuration')}</div>
<button type="submit" class="btn btn-sm bg-destinations" class:loading disabled={loading} <button type="submit" class="btn btn-sm bg-destinations w-full lg:w-fit" class:loading disabled={loading}
>{loading >{loading
? payload.isCoolifyProxyUsed ? payload.isCoolifyProxyUsed
? $t('destination.new.saving_and_configuring_proxy') ? $t('destination.new.saving_and_configuring_proxy')
@@ -48,12 +48,12 @@
: $t('forms.save')}</button : $t('forms.save')}</button
> >
</div> </div>
<div class="mt-2 grid grid-cols-2 items-center px-10"> <div class="mt-2 grid grid-cols-2 items-center lg:pl-10">
<label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label> <label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label>
<input required name="name" placeholder={$t('forms.name')} bind:value={payload.name} /> <input required name="name" placeholder={$t('forms.name')} bind:value={payload.name} />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:pl-10">
<label for="remoteIpAddress" class="text-base font-bold text-stone-100" <label for="remoteIpAddress" class="text-base font-bold text-stone-100"
>{$t('forms.ip_address')}</label >{$t('forms.ip_address')}</label
> >
@@ -65,7 +65,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:pl-10">
<label for="remoteUser" class="text-base font-bold text-stone-100">{$t('forms.user')}</label> <label for="remoteUser" class="text-base font-bold text-stone-100">{$t('forms.user')}</label>
<input <input
required required
@@ -75,7 +75,7 @@
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:pl-10">
<label for="remotePort" class="text-base font-bold text-stone-100">{$t('forms.port')}</label> <label for="remotePort" class="text-base font-bold text-stone-100">{$t('forms.port')}</label>
<input <input
required required
@@ -84,7 +84,7 @@
bind:value={payload.remotePort} bind:value={payload.remotePort}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:pl-10">
<label for="network" class="text-base font-bold text-stone-100">{$t('forms.network')}</label> <label for="network" class="text-base font-bold text-stone-100">{$t('forms.network')}</label>
<input <input
required required
@@ -93,7 +93,7 @@
bind:value={payload.network} bind:value={payload.network}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:pl-10">
<Setting <Setting
id="isCoolifyProxyUsed" id="isCoolifyProxyUsed"
bind:setting={payload.isCoolifyProxyUsed} bind:setting={payload.isCoolifyProxyUsed}

View File

@@ -36,8 +36,8 @@
}); });
</script> </script>
<div class="flex space-x-1 p-6 font-bold"> <nav class="header">
<div class="mr-4 text-2xl tracking-tight">{$t('index.destinations')}</div> <h1 class="mr-4 text-2xl font-bold">{$t('index.destinations')}</h1>
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<a href="/destinations/new" class="btn btn-square btn-sm bg-destinations"> <a href="/destinations/new" class="btn btn-square btn-sm bg-destinations">
<svg <svg
@@ -55,8 +55,9 @@
> >
</a> </a>
{/if} {/if}
</div> </nav>
<div class="flex-col justify-center mt-10 pb-12 sm:pb-16"> <br />
<div class="flex-col justify-center mt-10 pb-12 sm:pb-16 lg:pt-16">
{#if !destinations || ownDestinations.length === 0} {#if !destinations || ownDestinations.length === 0}
<div class="flex-col"> <div class="flex-col">
<div class="text-center text-xl font-bold">{$t('destination.no_destination_found')}</div> <div class="text-center text-xl font-bold">{$t('destination.no_destination_found')}</div>

View File

@@ -106,8 +106,8 @@
} }
</script> </script>
<div class="flex space-x-1 p-6 font-bold"> <nav class="header">
<div class="mr-4 text-2xl tracking-tight">Identity and Access Management</div> <h1 class="mr-4 text-2xl tracking-tight font-bold">Identity and Access Management</h1>
<button on:click={newTeam} class="btn btn-square btn-sm bg-iam"> <button on:click={newTeam} class="btn btn-square btn-sm bg-iam">
<svg <svg
class="h-6 w-6" class="h-6 w-6"
@@ -123,10 +123,11 @@
/></svg /></svg
> >
</button> </button>
</div> </nav>
<br />
{#if invitations.length > 0} {#if invitations.length > 0}
<div class="mx-auto max-w-4xl px-6 py-4"> <div class="mx-auto max-w-6xl px-6 py-4">
<div class="title font-bold">Pending invitations</div> <div class="title font-bold">Pending invitations</div>
<div class="pt-10 text-center"> <div class="pt-10 text-center">
{#each invitations as invitation} {#each invitations as invitation}
@@ -148,7 +149,7 @@
</div> </div>
</div> </div>
{/if} {/if}
<div class="mx-auto max-w-4xl px-6 py-4"> <div class="mx-auto max-w-6xl px-6 py-4">
{#if $appSession.teamId === '0' && accounts.length > 0} {#if $appSession.teamId === '0' && accounts.length > 0}
<div class="title font-bold">Accounts</div> <div class="title font-bold">Accounts</div>
{:else} {:else}
@@ -188,7 +189,7 @@
</div> </div>
</div> </div>
<div class="mx-auto max-w-4xl px-6"> <div class="mx-auto max-w-6xl px-6">
<div class="title font-bold">Teams</div> <div class="title font-bold">Teams</div>
<div class="flex-col items-center justify-center pt-10"> <div class="flex-col items-center justify-center pt-10">
<div class="flex flex-row flex-wrap justify-center px-2 pb-10 md:flex-row"> <div class="flex flex-row flex-wrap justify-center px-2 pb-10 md:flex-row">

View File

@@ -87,7 +87,7 @@
<span class="arrow-right-applications px-1 text-fuchsia-500">></span> <span class="arrow-right-applications px-1 text-fuchsia-500">></span>
<span class="pr-2">{team.name}</span> <span class="pr-2">{team.name}</span>
</div> </div>
<div class="mx-auto max-w-4xl px-6"> <div class="mx-auto max-w-6xl px-6">
<form on:submit|preventDefault={handleSubmit} class=" py-4"> <form on:submit|preventDefault={handleSubmit} class=" py-4">
<div class="flex space-x-1 pb-5"> <div class="flex space-x-1 pb-5">
<div class="title font-bold">{$t('index.settings')}</div> <div class="title font-bold">{$t('index.settings')}</div>

View File

@@ -28,8 +28,7 @@
export let destinations: any; export let destinations: any;
let filtered: any = setInitials(); let filtered: any = setInitials();
import { get, post } from '$lib/api'; import { get } from '$lib/api';
import Usage from '$lib/components/Usage.svelte';
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import { asyncSleep, getRndInteger } from '$lib/common'; import { asyncSleep, getRndInteger } from '$lib/common';
import { appSession, search, addToast} from '$lib/store'; import { appSession, search, addToast} from '$lib/store';
@@ -274,17 +273,13 @@
</script> </script>
<div class="flex space-x-1 p-6 font-bold"> <nav class="header">
<div class="mr-4 text-2xl tracking-tight">{$t('index.dashboard')}</div> <h1 class="mr-4 text-2xl font-bold">{$t('index.dashboard')}</h1>
{#if $appSession.isAdmin && (applications.length !== 0 || destinations.length !== 0 || databases.length !== 0 || services.length !== 0 || gitSources.length !== 0 || destinations.length !== 0)} {#if $appSession.isAdmin && (applications.length !== 0 || destinations.length !== 0 || databases.length !== 0 || services.length !== 0 || gitSources.length !== 0 || destinations.length !== 0)}
<NewResource /> <NewResource />
{/if} {/if}
</nav>
</div> <div class="container lg:mx-auto lg:p-0 px-8 pt-5">
<div class="container lg:mx-auto lg:p-0 px-8 p-5">
<!-- {#if $appSession.teamId === '0'}
<Usage />
{/if} -->
{#if applications.length !== 0 || destinations.length !== 0 || databases.length !== 0 || services.length !== 0 || gitSources.length !== 0 || destinations.length !== 0} {#if applications.length !== 0 || destinations.length !== 0 || databases.length !== 0 || services.length !== 0 || gitSources.length !== 0 || destinations.length !== 0}
<div class="form-control"> <div class="form-control">
<div class="input-group flex w-full"> <div class="input-group flex w-full">
@@ -317,8 +312,8 @@
on:input={() => doSearch()} on:input={() => doSearch()}
/> />
</div> </div>
<label for="search" class="label w-full"> <label for="search" class="label w-full mt-3">
<span class="label-text text-xs flex flex-wrap gap-2 items-center"> <span class="label-text text-xs flex flex-wrap gap-2 items-center">
<button <button
class:bg-coollabs={$search === '!notmine'} class:bg-coollabs={$search === '!notmine'}
class="badge badge-lg text-white text-xs rounded" class="badge badge-lg text-white text-xs rounded"

View File

@@ -29,10 +29,10 @@
} }
</script> </script>
<div class="flex space-x-1 p-6 font-bold"> <div class="header">
<div class="mr-4 text-2xl tracking-tight">Servers</div> <h1 class="text-2xl font-bold">Servers</h1>
</div> </div>
<div class="container lg:mx-auto lg:p-0 px-8 p-5"> <div class="container lg:mx-auto lg:p-0 px-8 p-5 lg:pt-20">
{#if servers.length > 0} {#if servers.length > 0}
<div class="grid grid-col gap-8 auto-cols-max grid-cols-1 p-4"> <div class="grid grid-col gap-8 auto-cols-max grid-cols-1 p-4">
{#each servers as server} {#each servers as server}

View File

@@ -50,6 +50,8 @@
<td> <td>
<input <input
style="min-width: 350px !important;"
id={isNewSecret ? 'secretName' : 'secretNameNew'} id={isNewSecret ? 'secretName' : 'secretNameNew'}
bind:value={name} bind:value={name}
required required
@@ -67,6 +69,7 @@
bind:value bind:value
required required
placeholder="J$#@UIO%HO#$U%H" placeholder="J$#@UIO%HO#$U%H"
inputStyle="min-width: 350px; !important"
/> />
</td> </td>

View File

@@ -10,117 +10,84 @@
<div class="title">Appwrite</div> <div class="title">Appwrite</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="space-y-2">
<label for="opensslKeyV1">Encryption Key</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<CopyPasswordField <label for="opensslKeyV1">Encryption Key</label>
name="opensslKeyV1" <CopyPasswordField
id="opensslKeyV1" name="opensslKeyV1"
isPasswordField id="opensslKeyV1"
value={service.appwrite.opensslKeyV1} isPasswordField
readonly value={service.appwrite.opensslKeyV1}
disabled readonly
/> disabled
/>
</div>
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="executorSecret">Executor Secret</label>
<CopyPasswordField
name="executorSecret"
id="executorSecret"
isPasswordField
value={service.appwrite.executorSecret}
readonly
disabled
/>
</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10">
<label for="executorSecret">Executor Secret</label>
<CopyPasswordField
name="executorSecret"
id="executorSecret"
isPasswordField
value={service.appwrite.executorSecret}
readonly
disabled
/>
</div>
<!-- <div class="flex space-x-1 py-5 font-bold">
<div class="title">Redis</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="redisPassword">Password</label>
<CopyPasswordField
name="redisPassword"
id="redisPassword"
isPasswordField
value={service.appwrite.redisPassword}
readonly
disabled
/>
</div> -->
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">MariaDB</div> <div class="title">MariaDB</div>
</div> </div>
<div class="space-y-2">
<!-- <div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="mariadbHost">MariaDB Host</label> <label for="mariadbUser">{$t('forms.username')}</label>
<CopyPasswordField <CopyPasswordField
name="mariadbHost" name="mariadbUser"
id="mariadbHost" id="mariadbUser"
value={service.appwrite.mariadbHost} value={service.appwrite.mariadbUser}
readonly readonly
disabled disabled
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2 ">
<label for="mariadbPort">MariaDB Port</label> <label for="mariadbPassword">{$t('forms.password')}</label>
<CopyPasswordField <CopyPasswordField
name="mariadbPort" id="mariadbPassword"
id="mariadbPort" isPasswordField
value={service.appwrite.mariadbPort} readonly
readonly disabled
disabled name="mariadbPassword"
/> value={service.appwrite.mariadbPassword}
</div> --> />
<div class="grid grid-cols-2 items-center px-10"> </div>
<label for="mariadbUser">{$t('forms.username')}</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<CopyPasswordField <label for="mariadbRootUser">Root User</label>
name="mariadbUser" <CopyPasswordField
id="mariadbUser" name="mariadbRootUser"
value={service.appwrite.mariadbUser} id="mariadbRootUser"
readonly value={service.appwrite.mariadbRootUser}
disabled readonly
/> disabled
</div> />
<div class="grid grid-cols-2 items-center px-10"> </div>
<label for="mariadbPassword">{$t('forms.password')}</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2 ">
<CopyPasswordField <label for="mariadbRootUserPassword">Root Password</label>
id="mariadbPassword" <CopyPasswordField
isPasswordField id="mariadbRootUserPassword"
readonly isPasswordField
disabled readonly
name="mariadbPassword" disabled
value={service.appwrite.mariadbPassword} name="mariadbRootUserPassword"
/> value={service.appwrite.mariadbRootUserPassword}
</div> />
<div class="grid grid-cols-2 items-center px-10"> </div>
<label for="mariadbRootUser">Root User</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<CopyPasswordField <label for="mariadbDatabase">{$t('index.database')}</label>
name="mariadbRootUser" <CopyPasswordField
id="mariadbRootUser" name="mariadbDatabase"
value={service.appwrite.mariadbRootUser} id="mariadbDatabase"
readonly value={service.appwrite.mariadbDatabase}
disabled readonly
/> disabled
</div> />
<div class="grid grid-cols-2 items-center px-10"> </div>
<label for="mariadbRootUserPassword">Root Password</label>
<CopyPasswordField
id="mariadbRootUserPassword"
isPasswordField
readonly
disabled
name="mariadbRootUserPassword"
value={service.appwrite.mariadbRootUserPassword}
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="mariadbDatabase">{$t('index.database')}</label>
<CopyPasswordField
name="mariadbDatabase"
id="mariadbDatabase"
value={service.appwrite.mariadbDatabase}
readonly
disabled
/>
</div> </div>

View File

@@ -21,163 +21,174 @@
<div class="title">Fider</div> <div class="title">Fider</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="space-y-2">
<label for="jwtSecret">JWT Secret</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<CopyPasswordField <label for="jwtSecret">JWT Secret</label>
name="jwtSecret" <CopyPasswordField
id="jwtSecret" name="jwtSecret"
isPasswordField id="jwtSecret"
value={service.fider.jwtSecret} isPasswordField
readonly value={service.fider.jwtSecret}
disabled readonly
/> disabled
</div> />
</div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="emailNoreply">Noreply Email</label> <label for="emailNoreply">Noreply Email</label>
<input <input
name="emailNoreply" class="w-full"
id="emailNoreply" name="emailNoreply"
type="email" id="emailNoreply"
required type="email"
readonly={readOnly} required
disabled={readOnly} readonly={readOnly}
bind:value={service.fider.emailNoreply} disabled={readOnly}
placeholder="{$t('forms.eg')}: noreply@yourdomain.com" bind:value={service.fider.emailNoreply}
/> placeholder="{$t('forms.eg')}: noreply@yourdomain.com"
/>
</div>
</div> </div>
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">Email</div> <div class="title">Email</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="space-y-2">
<label for="emailMailgunApiKey">Mailgun API Key</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<CopyPasswordField <label for="emailMailgunApiKey">Mailgun API Key</label>
name="emailMailgunApiKey" <CopyPasswordField
id="emailMailgunApiKey" name="emailMailgunApiKey"
isPasswordField id="emailMailgunApiKey"
bind:value={service.fider.emailMailgunApiKey} isPasswordField
readonly={readOnly} bind:value={service.fider.emailMailgunApiKey}
disabled={readOnly} readonly={readOnly}
placeholder="{$t('forms.eg')}: key-yourkeygoeshere" disabled={readOnly}
/> placeholder="{$t('forms.eg')}: key-yourkeygoeshere"
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="emailMailgunDomain">Mailgun Domain</label>
<input
name="emailMailgunDomain"
id="emailMailgunDomain"
readonly={readOnly}
disabled={readOnly}
bind:value={service.fider.emailMailgunDomain}
placeholder="{$t('forms.eg')}: yourdomain.com"
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="emailMailgunRegion">Mailgun Region</label>
<div class="custom-select-wrapper">
<Select
id="baseBuildImages"
items={mailgunRegions}
showIndicator
on:select={(event) => (service.fider.emailMailgunRegion = event.detail.value)}
value={service.fider.emailMailgunRegion || 'EU'}
isClearable={false}
/> />
</div> </div>
</div>
<div class="flex space-x-1 py-5 px-10 font-bold"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<div class="text-lg">Or</div> <label for="emailMailgunDomain">Mailgun Domain</label>
</div> <input
<div class="grid grid-cols-2 items-center px-10"> class="w-full"
<label for="emailSmtpHost">SMTP Host</label> name="emailMailgunDomain"
<input id="emailMailgunDomain"
name="emailSmtpHost" readonly={readOnly}
id="emailSmtpHost" disabled={readOnly}
readonly={readOnly} bind:value={service.fider.emailMailgunDomain}
disabled={readOnly} placeholder="{$t('forms.eg')}: yourdomain.com"
bind:value={service.fider.emailSmtpHost} />
placeholder="{$t('forms.eg')}: smtp.yourdomain.com" </div>
/> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
</div> <label for="emailMailgunRegion">Mailgun Region</label>
<div class="grid grid-cols-2 items-center px-10"> <div class="custom-select-wrapper">
<label for="emailSmtpPort">SMTP Port</label> <Select
<input id="baseBuildImages"
name="emailSmtpPort" items={mailgunRegions}
id="emailSmtpPort" showIndicator
readonly={readOnly} on:select={(event) => (service.fider.emailMailgunRegion = event.detail.value)}
disabled={readOnly} value={service.fider.emailMailgunRegion || 'EU'}
bind:value={service.fider.emailSmtpPort} isClearable={false}
placeholder="{$t('forms.eg')}: 587" />
/> </div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10">
<label for="emailSmtpUser">SMTP User</label> <div class="flex space-x-1 py-5 lg:px-10 px-2 font-bold">
<input <div class="text-lg">Or</div>
name="emailSmtpUser" </div>
id="emailSmtpUser" <div class="grid grid-cols-2 items-center lg:px-10 px-2">
readonly={readOnly} <label for="emailSmtpHost">SMTP Host</label>
disabled={readOnly} <input
bind:value={service.fider.emailSmtpUser} class="w-full"
placeholder="{$t('forms.eg')}: user@yourdomain.com" name="emailSmtpHost"
/> id="emailSmtpHost"
</div> readonly={readOnly}
<div class="grid grid-cols-2 items-center px-10"> disabled={readOnly}
<label for="emailSmtpPassword">SMTP Password</label> bind:value={service.fider.emailSmtpHost}
<CopyPasswordField placeholder="{$t('forms.eg')}: smtp.yourdomain.com"
name="emailSmtpPassword" />
id="emailSmtpPassword" </div>
isPasswordField <div class="grid grid-cols-2 items-center lg:px-10 px-2">
bind:value={service.fider.emailSmtpPassword} <label for="emailSmtpPort">SMTP Port</label>
readonly={readOnly} <input
disabled={readOnly} class="w-full"
placeholder="{$t('forms.eg')}: s0m3p4ssw0rd" name="emailSmtpPort"
/> id="emailSmtpPort"
</div> readonly={readOnly}
<div class="grid grid-cols-2 items-center px-10"> disabled={readOnly}
<label for="emailSmtpEnableStartTls">SMTP Start TLS</label> bind:value={service.fider.emailSmtpPort}
<input placeholder="{$t('forms.eg')}: 587"
name="emailSmtpEnableStartTls" />
id="emailSmtpEnableStartTls" </div>
readonly={readOnly} <div class="grid grid-cols-2 items-center lg:px-10 px-2">
disabled={readOnly} <label for="emailSmtpUser">SMTP User</label>
bind:value={service.fider.emailSmtpEnableStartTls} <input
placeholder="{$t('forms.eg')}: true" class="w-full"
/> name="emailSmtpUser"
id="emailSmtpUser"
readonly={readOnly}
disabled={readOnly}
bind:value={service.fider.emailSmtpUser}
placeholder="{$t('forms.eg')}: user@yourdomain.com"
/>
</div>
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="emailSmtpPassword">SMTP Password</label>
<CopyPasswordField
name="emailSmtpPassword"
id="emailSmtpPassword"
isPasswordField
bind:value={service.fider.emailSmtpPassword}
readonly={readOnly}
disabled={readOnly}
placeholder="{$t('forms.eg')}: s0m3p4ssw0rd"
/>
</div>
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="emailSmtpEnableStartTls">SMTP Start TLS</label>
<input
class="w-full"
name="emailSmtpEnableStartTls"
id="emailSmtpEnableStartTls"
readonly={readOnly}
disabled={readOnly}
bind:value={service.fider.emailSmtpEnableStartTls}
placeholder="{$t('forms.eg')}: true"
/>
</div>
</div> </div>
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">PostgreSQL</div> <div class="title">PostgreSQL</div>
</div> </div>
<div class="space-y-2">
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="postgresqlUser">{$t('forms.username')}</label> <label for="postgresqlUser">{$t('forms.username')}</label>
<CopyPasswordField <CopyPasswordField
name="postgresqlUser" name="postgresqlUser"
id="postgresqlUser" id="postgresqlUser"
value={service.fider.postgresqlUser} value={service.fider.postgresqlUser}
readonly readonly
disabled disabled
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="postgresqlPassword">{$t('forms.password')}</label> <label for="postgresqlPassword">{$t('forms.password')}</label>
<CopyPasswordField <CopyPasswordField
id="postgresqlPassword" id="postgresqlPassword"
isPasswordField isPasswordField
readonly readonly
disabled disabled
name="postgresqlPassword" name="postgresqlPassword"
value={service.fider.postgresqlPassword} value={service.fider.postgresqlPassword}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="postgresqlDatabase">{$t('index.database')}</label> <label for="postgresqlDatabase">{$t('index.database')}</label>
<CopyPasswordField <CopyPasswordField
name="postgresqlDatabase" name="postgresqlDatabase"
id="postgresqlDatabase" id="postgresqlDatabase"
value={service.fider.postgresqlDatabase} value={service.fider.postgresqlDatabase}
readonly readonly
disabled disabled
/> />
</div>
</div> </div>

View File

@@ -8,12 +8,14 @@
<div class="flex space-x-1 py-5"> <div class="flex space-x-1 py-5">
<div class="title"> <div class="title">
Ghost <Explainer explanation="You can change these values in the Ghost admin panel." /> Ghost <Explainer explanation="You can change these values in the <span class='text-settings'>Ghost admin panel<span>." />
</div> </div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="space-y-2">
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="email">{$t('forms.default_email_address')}</label> <label for="email">{$t('forms.default_email_address')}</label>
<input <input
class="w-full"
name="email" name="email"
id="email" id="email"
disabled disabled
@@ -23,7 +25,7 @@
required required
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="defaultPassword">{$t('forms.default_password')}</label> <label for="defaultPassword">{$t('forms.default_password')}</label>
<CopyPasswordField <CopyPasswordField
id="defaultPassword" id="defaultPassword"
@@ -34,10 +36,12 @@
value={service.ghost.defaultPassword} value={service.ghost.defaultPassword}
/> />
</div> </div>
</div>
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">MariaDB</div> <div class="title">MariaDB</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="space-y-2">
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="mariadbUser">{$t('forms.username')}</label> <label for="mariadbUser">{$t('forms.username')}</label>
<CopyPasswordField <CopyPasswordField
name="mariadbUser" name="mariadbUser"
@@ -47,7 +51,7 @@
disabled disabled
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="mariadbPassword">{$t('forms.password')}</label> <label for="mariadbPassword">{$t('forms.password')}</label>
<CopyPasswordField <CopyPasswordField
id="mariadbPassword" id="mariadbPassword"
@@ -58,9 +62,10 @@
value={service.ghost.mariadbPassword} value={service.ghost.mariadbPassword}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="mariadbDatabase">{$t('index.database')}</label> <label for="mariadbDatabase">{$t('index.database')}</label>
<input <input
class="w-full"
name="mariadbDatabase" name="mariadbDatabase"
id="mariadbDatabase" id="mariadbDatabase"
required required
@@ -70,7 +75,7 @@
placeholder="{$t('forms.eg')}: ghost_db" placeholder="{$t('forms.eg')}: ghost_db"
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="mariadbRootUser">{$t('forms.root_db_user')}</label> <label for="mariadbRootUser">{$t('forms.root_db_user')}</label>
<CopyPasswordField <CopyPasswordField
id="mariadbRootUser" id="mariadbRootUser"
@@ -80,7 +85,7 @@
value={service.ghost.mariadbRootUser} value={service.ghost.mariadbRootUser}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="mariadbRootUserPassword">{$t('forms.root_db_password')}</label> <label for="mariadbRootUserPassword">{$t('forms.root_db_password')}</label>
<CopyPasswordField <CopyPasswordField
id="mariadbRootUserPassword" id="mariadbRootUserPassword"
@@ -91,3 +96,4 @@
value={service.ghost.mariadbRootUserPassword} value={service.ghost.mariadbRootUserPassword}
/> />
</div> </div>
</div>

View File

@@ -53,7 +53,7 @@
<div class="title">GlitchTip</div> <div class="title">GlitchTip</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<Setting <Setting
id="enableOpenUserRegistration" id="enableOpenUserRegistration"
bind:setting={service.glitchTip.enableOpenUserRegistration} bind:setting={service.glitchTip.enableOpenUserRegistration}
@@ -74,171 +74,173 @@
<div class="flex space-x-1 py-2 font-bold"> <div class="flex space-x-1 py-2 font-bold">
<div class="subtitle">Email settings</div> <div class="subtitle">Email settings</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="space-y-2">
<Setting <div class="grid grid-cols-2 items-center lg:px-10 px-2">
id="emailSmtpUseTls" <Setting
bind:setting={service.glitchTip.emailSmtpUseTls} id="emailSmtpUseTls"
{loading} bind:setting={service.glitchTip.emailSmtpUseTls}
disabled={$status.service.isRunning} {loading}
on:click={() => changeSettings('emailSmtpUseTls')} disabled={$status.service.isRunning}
title="Use TLS for SMTP" on:click={() => changeSettings('emailSmtpUseTls')}
description={''} title="Use TLS for SMTP"
/> description={''}
</div> />
</div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<Setting <Setting
id="emailSmtpUseSsl" id="emailSmtpUseSsl"
bind:setting={service.glitchTip.emailSmtpUseSsl} bind:setting={service.glitchTip.emailSmtpUseSsl}
{loading} {loading}
disabled={$status.service.isRunning} disabled={$status.service.isRunning}
on:click={() => changeSettings('emailSmtpUseSsl')} on:click={() => changeSettings('emailSmtpUseSsl')}
title="Use SSL for SMTP" title="Use SSL for SMTP"
description={''} description={''}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="defaultEmailFrom">Default Email From</label> <label for="defaultEmailFrom">Default Email From</label>
<CopyPasswordField <CopyPasswordField
required required
name="defaultEmailFrom" name="defaultEmailFrom"
id="defaultEmailFrom" id="defaultEmailFrom"
bind:value={service.glitchTip.defaultEmailFrom} bind:value={service.glitchTip.defaultEmailFrom}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="emailSmtpHost">SMTP Host</label> <label for="emailSmtpHost">SMTP Host</label>
<CopyPasswordField <CopyPasswordField
name="emailSmtpHost" name="emailSmtpHost"
id="emailSmtpHost" id="emailSmtpHost"
bind:value={service.glitchTip.emailSmtpHost} bind:value={service.glitchTip.emailSmtpHost}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="emailSmtpPort">SMTP Port</label> <label for="emailSmtpPort">SMTP Port</label>
<CopyPasswordField <CopyPasswordField
name="emailSmtpPort" name="emailSmtpPort"
id="emailSmtpPort" id="emailSmtpPort"
bind:value={service.glitchTip.emailSmtpPort} bind:value={service.glitchTip.emailSmtpPort}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="emailSmtpUser">SMTP User</label> <label for="emailSmtpUser">SMTP User</label>
<CopyPasswordField <CopyPasswordField
name="emailSmtpUser" name="emailSmtpUser"
id="emailSmtpUser" id="emailSmtpUser"
bind:value={service.glitchTip.emailSmtpUser} bind:value={service.glitchTip.emailSmtpUser}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="emailSmtpPassword">SMTP Password</label> <label for="emailSmtpPassword">SMTP Password</label>
<CopyPasswordField <CopyPasswordField
name="emailSmtpPassword" name="emailSmtpPassword"
id="emailSmtpPassword" id="emailSmtpPassword"
bind:value={service.glitchTip.emailSmtpPassword} bind:value={service.glitchTip.emailSmtpPassword}
isPasswordField isPasswordField
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="emailBackend">Email Backend</label> <label for="emailBackend">Email Backend</label>
<CopyPasswordField <CopyPasswordField
name="emailBackend" name="emailBackend"
id="emailBackend" id="emailBackend"
bind:value={service.glitchTip.emailBackend} bind:value={service.glitchTip.emailBackend}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="mailgunApiKey">Mailgun API Key</label> <label for="mailgunApiKey">Mailgun API Key</label>
<CopyPasswordField <CopyPasswordField
name="mailgunApiKey" name="mailgunApiKey"
id="mailgunApiKey" id="mailgunApiKey"
bind:value={service.glitchTip.mailgunApiKey} bind:value={service.glitchTip.mailgunApiKey}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="sendgridApiKey">SendGrid API Key</label> <label for="sendgridApiKey">SendGrid API Key</label>
<CopyPasswordField <CopyPasswordField
name="sendgridApiKey" name="sendgridApiKey"
id="sendgridApiKey" id="sendgridApiKey"
bind:value={service.glitchTip.sendgridApiKey} bind:value={service.glitchTip.sendgridApiKey}
/> />
</div> </div>
<div class="flex space-x-1 py-2 font-bold"> <div class="flex space-x-1 py-2 font-bold">
<div class="subtitle">Default User & Superuser</div> <div class="subtitle">Default User & Superuser</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="defaultEmail">{$t('forms.email')}</label> <label for="defaultEmail">{$t('forms.email')}</label>
<CopyPasswordField <CopyPasswordField
name="defaultEmail" name="defaultEmail"
id="defaultEmail" id="defaultEmail"
bind:value={service.glitchTip.defaultEmail} bind:value={service.glitchTip.defaultEmail}
readonly readonly
disabled disabled
/> />
</div>
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="defaultUsername">{$t('forms.username')}</label>
<CopyPasswordField
name="defaultUsername"
id="defaultUsername"
bind:value={service.glitchTip.defaultUsername}
readonly
disabled
/>
</div>
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="defaultPassword">{$t('forms.password')}</label>
<CopyPasswordField
name="defaultPassword"
id="defaultPassword"
bind:value={service.glitchTip.defaultPassword}
readonly
disabled
isPasswordField
/>
</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10">
<label for="defaultUsername">{$t('forms.username')}</label>
<CopyPasswordField
name="defaultUsername"
id="defaultUsername"
bind:value={service.glitchTip.defaultUsername}
readonly
disabled
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="defaultPassword">{$t('forms.password')}</label>
<CopyPasswordField
name="defaultPassword"
id="defaultPassword"
bind:value={service.glitchTip.defaultPassword}
readonly
disabled
isPasswordField
/>
</div>
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">PostgreSQL</div> <div class="title">PostgreSQL</div>
</div> </div>
<div class="space-y-2">
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="postgresqlUser">{$t('forms.username')}</label> <label for="postgresqlUser">{$t('forms.username')}</label>
<CopyPasswordField <CopyPasswordField
name="postgresqlUser" name="postgresqlUser"
id="postgresqlUser" id="postgresqlUser"
bind:value={service.glitchTip.postgresqlUser} bind:value={service.glitchTip.postgresqlUser}
readonly readonly
disabled disabled
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="postgresqlPassword">{$t('forms.password')}</label> <label for="postgresqlPassword">{$t('forms.password')}</label>
<CopyPasswordField <CopyPasswordField
id="postgresqlPassword" id="postgresqlPassword"
isPasswordField isPasswordField
readonly readonly
disabled disabled
name="postgresqlPassword" name="postgresqlPassword"
bind:value={service.glitchTip.postgresqlPassword} bind:value={service.glitchTip.postgresqlPassword}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="postgresqlDatabase">{$t('index.database')}</label> <label for="postgresqlDatabase">{$t('index.database')}</label>
<CopyPasswordField <CopyPasswordField
name="postgresqlDatabase" name="postgresqlDatabase"
id="postgresqlDatabase" id="postgresqlDatabase"
bind:value={service.glitchTip.postgresqlDatabase} bind:value={service.glitchTip.postgresqlDatabase}
readonly readonly
disabled disabled
/> />
</div>
</div> </div>

View File

@@ -8,7 +8,7 @@
<div class="title">Hasura</div> <div class="title">Hasura</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="graphQLAdminPassword">GraphQL Admin Password</label> <label for="graphQLAdminPassword">GraphQL Admin Password</label>
<CopyPasswordField <CopyPasswordField
name="graphQLAdminPassword" name="graphQLAdminPassword"
@@ -24,34 +24,36 @@
<div class="title">PostgreSQL</div> <div class="title">PostgreSQL</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="space-y-2">
<label for="postgresqlUser">{$t('forms.username')}</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<CopyPasswordField <label for="postgresqlUser">{$t('forms.username')}</label>
name="postgresqlUser" <CopyPasswordField
id="postgresqlUser" name="postgresqlUser"
value={service.hasura.postgresqlUser} id="postgresqlUser"
readonly value={service.hasura.postgresqlUser}
disabled readonly
/> disabled
</div> />
<div class="grid grid-cols-2 items-center px-10"> </div>
<label for="postgresqlPassword">{$t('forms.password')}</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<CopyPasswordField <label for="postgresqlPassword">{$t('forms.password')}</label>
id="postgresqlPassword" <CopyPasswordField
isPasswordField id="postgresqlPassword"
readonly isPasswordField
disabled readonly
name="postgresqlPassword" disabled
value={service.hasura.postgresqlPassword} name="postgresqlPassword"
/> value={service.hasura.postgresqlPassword}
</div> />
<div class="grid grid-cols-2 items-center px-10"> </div>
<label for="postgresqlDatabase">{$t('index.database')}</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<CopyPasswordField <label for="postgresqlDatabase">{$t('index.database')}</label>
name="postgresqlDatabase" <CopyPasswordField
id="postgresqlDatabase" name="postgresqlDatabase"
value={service.hasura.postgresqlDatabase} id="postgresqlDatabase"
readonly value={service.hasura.postgresqlDatabase}
disabled readonly
/> disabled
/>
</div>
</div> </div>

View File

@@ -7,7 +7,7 @@
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">MeiliSearch</div> <div class="title">MeiliSearch</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="masterKey">{$t('forms.admin_api_key')}</label> <label for="masterKey">{$t('forms.admin_api_key')}</label>
<CopyPasswordField <CopyPasswordField
id="masterKey" id="masterKey"

View File

@@ -8,38 +8,42 @@
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">MinIO</div> <div class="title">MinIO</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="space-y-2">
<label for="rootUser">{$t('forms.root_user')}</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<input <label for="rootUser">{$t('forms.root_user')}</label>
name="rootUser"
id="rootUser"
placeholder={$t('forms.username')}
value={service.minio.rootUser}
disabled
readonly
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="rootUserPassword">{$t('forms.roots_password')}</label>
<CopyPasswordField
id="rootUserPassword"
isPasswordField
readonly
disabled
name="rootUserPassword"
value={service.minio.rootUserPassword}
/>
</div>
{#if !service.minio.apiFqdn}
<div class="grid grid-cols-2 items-center px-10">
<label for="publicPort">{$t('forms.api_port')}</label>
<input <input
name="publicPort" class="w-full"
id="publicPort" name="rootUser"
value={service.minio.publicPort} id="rootUser"
placeholder={$t('forms.username')}
value={service.minio.rootUser}
disabled disabled
readonly readonly
placeholder={$t('forms.generated_automatically_after_start')}
/> />
</div> </div>
{/if} <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="rootUserPassword">{$t('forms.roots_password')}</label>
<CopyPasswordField
id="rootUserPassword"
isPasswordField
readonly
disabled
name="rootUserPassword"
value={service.minio.rootUserPassword}
/>
</div>
{#if !service.minio.apiFqdn}
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="publicPort">{$t('forms.api_port')}</label>
<input
class="w-full"
name="publicPort"
id="publicPort"
value={service.minio.publicPort}
disabled
readonly
placeholder={$t('forms.generated_automatically_after_start')}
/>
</div>
{/if}
</div>

View File

@@ -8,9 +8,10 @@
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">Moodle</div> <div class="title">Moodle</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="email">{$t('forms.default_email_address')}</label> <label class="text-base font-bold text-stone-100" for="email">{$t('forms.default_email_address')}</label>
<input <input
class="w-full"
name="email" name="email"
id="email" id="email"
required required
@@ -20,8 +21,8 @@
value={service.moodle.defaultEmail} value={service.moodle.defaultEmail}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="defaultUsername">Default Username</label> <label class="text-base font-bold text-stone-100" for="defaultUsername">Default Username</label>
<CopyPasswordField <CopyPasswordField
id="defaultUsername" id="defaultUsername"
required required
@@ -31,8 +32,8 @@
value={service.moodle.defaultUsername} value={service.moodle.defaultUsername}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="defaultPassword">{$t('forms.default_password')}</label> <label class="text-base font-bold text-stone-100" for="defaultPassword">{$t('forms.default_password')}</label>
<CopyPasswordField <CopyPasswordField
id="defaultPassword" id="defaultPassword"
isPasswordField isPasswordField
@@ -46,8 +47,8 @@
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">MariaDB</div> <div class="title">MariaDB</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="mariadbUser">{$t('forms.username')}</label> <label class="text-base font-bold text-stone-100" for="mariadbUser">{$t('forms.username')}</label>
<CopyPasswordField <CopyPasswordField
name="mariadbUser" name="mariadbUser"
id="mariadbUser" id="mariadbUser"
@@ -56,8 +57,8 @@
disabled disabled
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="mariadbPassword">{$t('forms.password')}</label> <label class="text-base font-bold text-stone-100" for="mariadbPassword">{$t('forms.password')}</label>
<CopyPasswordField <CopyPasswordField
id="mariadbPassword" id="mariadbPassword"
isPasswordField isPasswordField
@@ -67,9 +68,10 @@
value={service.moodle.mariadbPassword} value={service.moodle.mariadbPassword}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="mariadbDatabase">{$t('index.database')}</label> <label class="text-base font-bold text-stone-100" for="mariadbDatabase">{$t('index.database')}</label>
<input <input
class="w-full"
name="mariadbDatabase" name="mariadbDatabase"
id="mariadbDatabase" id="mariadbDatabase"
required required
@@ -79,8 +81,8 @@
placeholder="{$t('forms.eg')}: moodle_db" placeholder="{$t('forms.eg')}: moodle_db"
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="mariadbRootUser">{$t('forms.root_db_user')}</label> <label class="text-base font-bold text-stone-100" for="mariadbRootUser">{$t('forms.root_db_user')}</label>
<CopyPasswordField <CopyPasswordField
id="mariadbRootUser" id="mariadbRootUser"
readonly readonly
@@ -89,8 +91,8 @@
value={service.moodle.mariadbRootUser} value={service.moodle.mariadbRootUser}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="mariadbRootUserPassword">{$t('forms.root_db_password')}</label> <label class="text-base font-bold text-stone-100" for="mariadbRootUserPassword">{$t('forms.root_db_password')}</label>
<CopyPasswordField <CopyPasswordField
id="mariadbRootUserPassword" id="mariadbRootUserPassword"
isPasswordField isPasswordField

View File

@@ -10,94 +10,94 @@
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">Plausible Analytics</div> <div class="title">Plausible Analytics</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="space-y-2">
<label for="scriptName" <div class="grid grid-cols-2 items-center lg:px-10 px-2">
>Script Name <Explainer <label for="scriptName"
explanation="Useful if you would like to rename the collector script to prevent it blocked by AdBlockers." >Script Name <Explainer
/></label explanation="Useful if you would like to rename the collector script to prevent it blocked by AdBlockers."
> /></label
<input >
name="scriptName" <input
id="scriptName" class="w-full"
readonly={!$appSession.isAdmin && !$status.service.isRunning} name="scriptName"
disabled={!$appSession.isAdmin || id="scriptName"
$status.service.isRunning || readonly={!$appSession.isAdmin && !$status.service.isRunning}
$status.service.initialLoading} disabled={!$appSession.isAdmin || $status.service.isRunning || $status.service.initialLoading}
placeholder="plausible.js" placeholder="plausible.js"
bind:value={service.plausibleAnalytics.scriptName} bind:value={service.plausibleAnalytics.scriptName}
required required
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="email">{$t('forms.email')}</label> <label for="email">{$t('forms.email')}</label>
<input <input
name="email" class="w-full"
id="email" name="email"
disabled={!$appSession.isAdmin || id="email"
$status.service.isRunning || disabled={!$appSession.isAdmin || $status.service.isRunning || $status.service.initialLoading}
$status.service.initialLoading} readonly={readOnly}
readonly={readOnly} placeholder={$t('forms.email')}
placeholder={$t('forms.email')} bind:value={service.plausibleAnalytics.email}
bind:value={service.plausibleAnalytics.email} required
required />
/> </div>
</div> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<div class="grid grid-cols-2 items-center px-10"> <label for="username">{$t('forms.username')}</label>
<label for="username">{$t('forms.username')}</label> <CopyPasswordField
<CopyPasswordField name="username"
name="username" id="username"
id="username" disabled={!$appSession.isAdmin || $status.service.isRunning || $status.service.initialLoading}
disabled={!$appSession.isAdmin || readonly={readOnly}
$status.service.isRunning || placeholder={$t('forms.username')}
$status.service.initialLoading} bind:value={service.plausibleAnalytics.username}
readonly={readOnly} required
placeholder={$t('forms.username')} />
bind:value={service.plausibleAnalytics.username} </div>
required <div class="grid grid-cols-2 items-center lg:px-10 px-2">
/> <label for="password">{$t('forms.password')}</label>
</div> <CopyPasswordField
<div class="grid grid-cols-2 items-center px-10"> id="password"
<label for="password">{$t('forms.password')}</label> isPasswordField
<CopyPasswordField readonly
id="password" disabled
isPasswordField name="password"
readonly value={service.plausibleAnalytics.password}
disabled />
name="password" </div>
value={service.plausibleAnalytics.password}
/>
</div> </div>
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">PostgreSQL</div> <div class="title">PostgreSQL</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="space-y-2">
<label for="postgresqlUser">{$t('forms.username')}</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<CopyPasswordField <label for="postgresqlUser">{$t('forms.username')}</label>
name="postgresqlUser" <CopyPasswordField
id="postgresqlUser" name="postgresqlUser"
value={service.plausibleAnalytics.postgresqlUser} id="postgresqlUser"
readonly value={service.plausibleAnalytics.postgresqlUser}
disabled readonly
/> disabled
</div> />
<div class="grid grid-cols-2 items-center px-10"> </div>
<label for="postgresqlPassword">{$t('forms.password')}</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<CopyPasswordField <label for="postgresqlPassword">{$t('forms.password')}</label>
id="postgresqlPassword" <CopyPasswordField
isPasswordField id="postgresqlPassword"
readonly isPasswordField
disabled readonly
name="postgresqlPassword" disabled
value={service.plausibleAnalytics.postgresqlPassword} name="postgresqlPassword"
/> value={service.plausibleAnalytics.postgresqlPassword}
</div> />
<div class="grid grid-cols-2 items-center px-10"> </div>
<label for="postgresqlDatabase">{$t('index.database')}</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<CopyPasswordField <label for="postgresqlDatabase">{$t('index.database')}</label>
name="postgresqlDatabase" <CopyPasswordField
id="postgresqlDatabase" name="postgresqlDatabase"
value={service.plausibleAnalytics.postgresqlDatabase} id="postgresqlDatabase"
readonly value={service.plausibleAnalytics.postgresqlDatabase}
disabled readonly
/> disabled
/>
</div>
</div> </div>

View File

@@ -8,7 +8,7 @@
<div class="title">SearXNG</div> <div class="title">SearXNG</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="secretKey">Secret Key</label> <label for="secretKey">Secret Key</label>
<CopyPasswordField <CopyPasswordField
name="secretKey" name="secretKey"
@@ -23,7 +23,7 @@
<div class="title">Redis</div> <div class="title">Redis</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="redisPassword">{$t('forms.password')}</label> <label for="redisPassword">{$t('forms.password')}</label>
<CopyPasswordField <CopyPasswordField
name="redisPassword" name="redisPassword"

View File

@@ -178,68 +178,63 @@
}); });
</script> </script>
<div class="mx-auto max-w-4xl px-6 pb-12"> <div class="mx-auto max-w-6xl px-6 pb-12">
<form on:submit|preventDefault={handleSubmit} class="py-4"> <form on:submit|preventDefault={handleSubmit} class="py-4">
<div class="flex space-x-1 pb-5"> <div class="flex space-x-1 pb-5 items-center">
<div class="title">{$t('general')}</div> <h1 class="title">{$t('general')}</h1>
{#if $appSession.isAdmin} <div class="flex flex-row space-y-3 items-center">
<button {#if $appSession.isAdmin}
type="submit" <button
class="btn btn-sm" type="submit"
class:bg-orange-600={forceSave} class="btn btn-sm"
class:hover:bg-orange-400={forceSave} class:bg-orange-600={forceSave}
class:loading={loading.save} class:hover:bg-orange-400={forceSave}
class:bg-services={!loading.save} class:loading={loading.save}
disabled={loading.save} class:bg-services={!loading.save}
>{loading.save disabled={loading.save}
? $t('forms.save') >{loading.save
: forceSave ? $t('forms.save')
? $t('forms.confirm_continue') : forceSave
: $t('forms.save')}</button ? $t('forms.confirm_continue')
> : $t('forms.save')}</button
{/if} >
{#if service.type === 'plausibleanalytics' && $status.service.isRunning} {/if}
<button {#if service.type === 'plausibleanalytics' && $status.service.isRunning}
class="btn btn-sm" <button
on:click|preventDefault={setEmailsToVerified} class="btn btn-sm"
disabled={loading.verification} on:click|preventDefault={setEmailsToVerified}
class:loading={loading.verification} disabled={loading.verification}
>{loading.verification class:loading={loading.verification}
? $t('forms.verifying') >{loading.verification
: $t('forms.verify_emails_without_smtp')}</button ? $t('forms.verifying')
> : $t('forms.verify_emails_without_smtp')}</button
<button >
class="btn btn-sm" <button
on:click|preventDefault={cleanupLogs} class="btn btn-sm"
disabled={loading.cleanup} on:click|preventDefault={cleanupLogs}
class:loading={loading.cleanup}>Cleanup Unnecessary Database Logs</button disabled={loading.cleanup}
> class:loading={loading.cleanup}>Cleanup Unnecessary Database Logs</button
{/if} >
{/if}
</div>
</div> </div>
<div class="grid grid-flow-row gap-2"> {#if service.type === 'minio' && !service.minio.apiFqdn && $status.service.isRunning}
{#if service.type === 'minio' && !service.minio.apiFqdn && $status.service.isRunning} <div class="py-5">
<div class="text-center"> <span class="font-bold text-red-500">IMPORTANT!</span> There was a small modification with Minio
<span class="font-bold text-red-500">IMPORTANT!</span> There was a small modification with in the latest version of Coolify. Now you can separate the Console URL from the API URL, so you
Minio in the latest version of Coolify. Now you can separate the Console URL from the API URL, could use both through SSL. But this proccess cannot be done automatically, so you have to stop
so you could use both through SSL. But this proccess cannot be done automatically, so you have your Minio instance, configure the new domain and start it back. Sorry for any inconvenience.
to stop your Minio instance, configure the new domain and start it back. Sorry for any inconvenience.
</div>
{/if}
<div class="mt-2 grid grid-cols-2 items-center px-10">
<label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label>
<div>
<input
readonly={!$appSession.isAdmin}
name="name"
id="name"
bind:value={service.name}
required
/>
</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> {/if}
<label for="version" class="text-base font-bold text-stone-100">Version / Tag</label>
<div class="grid gap-4 grid-cols-1 grid-rows-1 lg:px-10 px-2">
<div class="mt-2 grid grid-cols-2 items-center">
<label for="name">{$t('forms.name')}</label>
<input name="name" id="name" class="w-full" bind:value={service.name} required />
</div>
<div class="grid grid-cols-2 items-center">
<label for="version">Version / Tag</label>
<a <a
href={$appSession.isAdmin && !$status.service.isRunning && !$status.service.initialLoading href={$appSession.isAdmin && !$status.service.isRunning && !$status.service.initialLoading
? `/services/${id}/configuration/version?from=/services/${id}` ? `/services/${id}/configuration/version?from=/services/${id}`
@@ -247,6 +242,7 @@
class="no-underline" class="no-underline"
> >
<input <input
class="w-full"
value={service.version} value={service.version}
id="service" id="service"
readonly readonly
@@ -255,10 +251,8 @@
/></a /></a
> >
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center">
<label for="destination" class="text-base font-bold text-stone-100" <label for="destination">{$t('application.destination')}</label>
>{$t('application.destination')}</label
>
<div> <div>
{#if service.destinationDockerId} {#if service.destinationDockerId}
<div class="no-underline"> <div class="no-underline">
@@ -266,17 +260,16 @@
value={service.destinationDocker.name} value={service.destinationDocker.name}
id="destination" id="destination"
disabled disabled
class="bg-transparent " class="bg-transparent w-full"
/> />
</div> </div>
{/if} {/if}
</div> </div>
</div> </div>
{#if service.type === 'minio'} {#if service.type === 'minio'}
<div class="grid grid-cols-2 px-10"> <div class="grid grid-cols-2 items-center">
<div class="flex-col "> <label for="fqdn">Console URL</label>
<label for="fqdn" class="pt-2 text-base font-bold text-stone-100">Console URL</label>
</div>
<CopyPasswordField <CopyPasswordField
placeholder="eg: https://console.min.io" placeholder="eg: https://console.min.io"
@@ -289,13 +282,10 @@
required required
/> />
</div> </div>
<div class="grid grid-cols-2 px-10"> <div class="grid grid-cols-2 items-center">
<div class="flex-col "> <label for="apiFqdn"
<label for="apiFqdn" class="pt-2 text-base font-bold text-stone-100" >API URL <Explainer explanation={$t('application.https_explainer')} /></label
>API URL <Explainer explanation={$t('application.https_explainer')} /></label >
>
</div>
<CopyPasswordField <CopyPasswordField
placeholder="eg: https://min.io" placeholder="eg: https://min.io"
readonly={!$appSession.isAdmin && !$status.service.isRunning} readonly={!$appSession.isAdmin && !$status.service.isRunning}
@@ -308,14 +298,11 @@
/> />
</div> </div>
{:else} {:else}
<div class="grid grid-cols-2 px-10"> <div class="grid grid-cols-2 items-center">
<div class="flex-col "> <label for="fqdn"
<label for="fqdn" class="pt-2 text-base font-bold text-stone-100" >{$t('application.url_fqdn')}
>{$t('application.url_fqdn')} <Explainer explanation={$t('application.https_explainer')} />
<Explainer explanation={$t('application.https_explainer')} /> </label>
</label>
</div>
<CopyPasswordField <CopyPasswordField
placeholder="eg: https://analytics.coollabs.io" placeholder="eg: https://analytics.coollabs.io"
readonly={!$appSession.isAdmin && !$status.service.isRunning} readonly={!$appSession.isAdmin && !$status.service.isRunning}
@@ -330,56 +317,49 @@
/> />
</div> </div>
{/if} {/if}
{#if forceSave} </div>
<div class="flex-col space-y-2 pt-4 text-center"> {#if forceSave}
{#if isNonWWWDomainOK} <div class="flex-col space-y-2 pt-4 text-center">
{#if isNonWWWDomainOK}
<button
class="btn btn-sm bg-green-600 hover:bg-green-500"
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)}
>DNS settings for {nonWWWDomain} is OK, click to recheck.</button
>
{:else}
<button
class="btn btn-sm bg-red-600 hover:bg-red-500"
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)}
>DNS settings for {nonWWWDomain} is invalid, click to recheck.</button
>
{/if}
{#if dualCerts}
{#if isWWWDomainOK}
<button <button
class="btn btn-sm bg-green-600 hover:bg-green-500" class="btn btn-sm bg-green-600 hover:bg-green-500"
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)} on:click|preventDefault={() => isDNSValid(getDomain(`www.${nonWWWDomain}`), true)}
>DNS settings for {nonWWWDomain} is OK, click to recheck.</button >DNS settings for www.{nonWWWDomain} is OK, click to recheck.</button
> >
{:else} {:else}
<button <button
class="btn btn-sm bg-red-600 hover:bg-red-500" class="btn btn-sm bg-red-600 hover:bg-red-500"
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)} on:click|preventDefault={() => isDNSValid(getDomain(`www.${nonWWWDomain}`), true)}
>DNS settings for {nonWWWDomain} is invalid, click to recheck.</button >DNS settings for www.{nonWWWDomain} is invalid, click to recheck.</button
> >
{/if} {/if}
{#if dualCerts} {/if}
{#if isWWWDomainOK}
<button
class="btn btn-sm bg-green-600 hover:bg-green-500"
on:click|preventDefault={() => isDNSValid(getDomain(`www.${nonWWWDomain}`), true)}
>DNS settings for www.{nonWWWDomain} is OK, click to recheck.</button
>
{:else}
<button
class="btn btn-sm bg-red-600 hover:bg-red-500"
on:click|preventDefault={() => isDNSValid(getDomain(`www.${nonWWWDomain}`), true)}
>DNS settings for www.{nonWWWDomain} is invalid, click to recheck.</button
>
{/if}
{/if}
</div>
{/if}
<div class="grid grid-cols-2 items-center px-10">
<Setting
id="dualCerts"
disabled={$status.service.isRunning}
dataTooltip={$t('forms.must_be_stopped_to_modify')}
bind:setting={dualCerts}
title={$t('application.ssl_www_and_non_www')}
description={$t('services.generate_www_non_www_ssl')}
on:click={() => !$status.service.isRunning && changeSettings('dualCerts')}
/>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> {/if}
<label for="exposePort" class="text-base font-bold text-stone-100"
<div class="grid grid-flow-row gap-2 lg:px-10 px-2 pt-4">
<div class="grid grid-cols-2 items-center">
<label for="exposePort"
>Exposed Port <Explainer >Exposed Port <Explainer
explanation={'You can expose your application to a port on the host system.<br><br>Useful if you would like to use your own reverse proxy or tunnel and also in development mode. Otherwise leave empty.'} explanation={'You can expose your application to a port on the host system.<br><br>Useful if you would like to use your own reverse proxy or tunnel and also in development mode. Otherwise leave empty.'}
/></label /></label
> >
<input <input
class="w-full"
readonly={!$appSession.isAdmin && !$status.service.isRunning} readonly={!$appSession.isAdmin && !$status.service.isRunning}
disabled={!$appSession.isAdmin || disabled={!$appSession.isAdmin ||
$status.service.isRunning || $status.service.isRunning ||
@@ -390,38 +370,48 @@
placeholder="12345" placeholder="12345"
/> />
</div> </div>
<div class="grid grid-cols-2 items-center">
{#if service.type === 'plausibleanalytics'} <Setting
<PlausibleAnalytics bind:service {readOnly} /> id="dualCerts"
{:else if service.type === 'minio'} disabled={$status.service.isRunning}
<MinIo {service} /> dataTooltip={$t('forms.must_be_stopped_to_modify')}
{:else if service.type === 'vscodeserver'} bind:setting={dualCerts}
<VsCodeServer {service} /> title={$t('application.ssl_www_and_non_www')}
{:else if service.type === 'wordpress'} description={$t('services.generate_www_non_www_ssl')}
<Wordpress bind:service {readOnly} {settings} /> on:click={() => !$status.service.isRunning && changeSettings('dualCerts')}
{:else if service.type === 'ghost'} />
<Ghost bind:service {readOnly} /> </div>
{:else if service.type === 'meilisearch'}
<MeiliSearch bind:service />
{:else if service.type === 'umami'}
<Umami bind:service />
{:else if service.type === 'hasura'}
<Hasura bind:service />
{:else if service.type === 'fider'}
<Fider bind:service {readOnly} />
{:else if service.type === 'appwrite'}
<Appwrite bind:service {readOnly} />
{:else if service.type === 'moodle'}
<Moodle bind:service {readOnly} />
{:else if service.type === 'glitchTip'}
<GlitchTip bind:service />
{:else if service.type === 'searxng'}
<Searxng bind:service />
{:else if service.type === 'weblate'}
<Weblate bind:service />
{:else if service.type === 'taiga'}
<Taiga bind:service />
{/if}
</div> </div>
{#if service.type === 'plausibleanalytics'}
<PlausibleAnalytics bind:service {readOnly} />
{:else if service.type === 'minio'}
<MinIo {service} />
{:else if service.type === 'vscodeserver'}
<VsCodeServer {service} />
{:else if service.type === 'wordpress'}
<Wordpress bind:service {readOnly} {settings} />
{:else if service.type === 'ghost'}
<Ghost bind:service {readOnly} />
{:else if service.type === 'meilisearch'}
<MeiliSearch bind:service />
{:else if service.type === 'umami'}
<Umami bind:service />
{:else if service.type === 'hasura'}
<Hasura bind:service />
{:else if service.type === 'fider'}
<Fider bind:service {readOnly} />
{:else if service.type === 'appwrite'}
<Appwrite bind:service {readOnly} />
{:else if service.type === 'moodle'}
<Moodle bind:service {readOnly} />
{:else if service.type === 'glitchTip'}
<GlitchTip bind:service />
{:else if service.type === 'searxng'}
<Searxng bind:service />
{:else if service.type === 'weblate'}
<Weblate bind:service />
{:else if service.type === 'taiga'}
<Taiga bind:service />
{/if}
</form> </form>
</div> </div>

View File

@@ -8,8 +8,8 @@
<div class="title">Taiga</div> <div class="title">Taiga</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="secretKey">Secret Key</label> <label class="text-base font-bold text-stone-100" for="secretKey">Secret Key</label>
<CopyPasswordField <CopyPasswordField
name="secretKey" name="secretKey"
id="secretKey" id="secretKey"
@@ -24,8 +24,8 @@
<div class="title">Django</div> <div class="title">Django</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="djangoAdminUser">Admin User</label> <label class="text-base font-bold text-stone-100" for="djangoAdminUser">Admin User</label>
<CopyPasswordField <CopyPasswordField
name="djangoAdminUser" name="djangoAdminUser"
id="djangoAdminUser" id="djangoAdminUser"
@@ -34,8 +34,8 @@
disabled disabled
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="djangoAdminPassword">Admin Password</label> <label class="text-base font-bold text-stone-100" for="djangoAdminPassword">Admin Password</label>
<CopyPasswordField <CopyPasswordField
name="djangoAdminPassword" name="djangoAdminPassword"
id="djangoAdminPassword" id="djangoAdminPassword"
@@ -49,8 +49,8 @@
<div class="title">RabbitMQ</div> <div class="title">RabbitMQ</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="rabbitMQUser">User</label> <label class="text-base font-bold text-stone-100" for="rabbitMQUser">User</label>
<CopyPasswordField <CopyPasswordField
name="rabbitMQUser" name="rabbitMQUser"
id="rabbitMQUser" id="rabbitMQUser"
@@ -59,8 +59,8 @@
disabled disabled
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="rabbitMQPassword">Password</label> <label class="text-base font-bold text-stone-100" for="rabbitMQPassword">Password</label>
<CopyPasswordField <CopyPasswordField
name="rabbitMQPassword" name="rabbitMQPassword"
id="rabbitMQPassword" id="rabbitMQPassword"
@@ -75,8 +75,8 @@
<div class="title">PostgreSQL</div> <div class="title">PostgreSQL</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="postgresqlHost">PostgreSQL Host</label> <label class="text-base font-bold text-stone-100" for="postgresqlHost">PostgreSQL Host</label>
<CopyPasswordField <CopyPasswordField
name="postgresqlHost" name="postgresqlHost"
id="postgresqlHost" id="postgresqlHost"
@@ -85,8 +85,8 @@
disabled disabled
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="postgresqlPort">PostgreSQL Port</label> <label class="text-base font-bold text-stone-100" for="postgresqlPort">PostgreSQL Port</label>
<CopyPasswordField <CopyPasswordField
name="postgresqlPort" name="postgresqlPort"
id="postgresqlPort" id="postgresqlPort"
@@ -95,8 +95,8 @@
disabled disabled
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="postgresqlUser">PostgreSQL User</label> <label class="text-base font-bold text-stone-100" for="postgresqlUser">PostgreSQL User</label>
<CopyPasswordField <CopyPasswordField
name="postgresqlUser" name="postgresqlUser"
id="postgresqlUser" id="postgresqlUser"
@@ -105,8 +105,8 @@
disabled disabled
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10">
<label for="postgresqlPassword">PostgreSQL Password</label> <label class="text-base font-bold text-stone-100" for="postgresqlPassword">PostgreSQL Password</label>
<CopyPasswordField <CopyPasswordField
name="postgresqlPassword" name="postgresqlPassword"
id="postgresqlPassword" id="postgresqlPassword"

View File

@@ -7,23 +7,33 @@
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">Umami</div> <div class="title">Umami</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="space-y-2">
<label for="adminUser">Admin User</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<input name="adminUser" id="adminUser" placeholder="admin" value="admin" disabled readonly /> <label for="adminUser">Admin User</label>
</div> <input
<div class="grid grid-cols-2 items-center px-10"> class="w-full"
<label for="umamiAdminPassword" name="adminUser"
>Initial Admin Password <Explainer id="adminUser"
explanation="It could be changed in Umami. <br>This is just the password set initially after the first start." placeholder="admin"
/></label value="admin"
> disabled
<CopyPasswordField readonly
isPasswordField />
name="umamiAdminPassword" </div>
id="umamiAdminPassword" <div class="grid grid-cols-2 items-center lg:px-10 px-2">
placeholder="admin" <label for="umamiAdminPassword"
value={service.umami.umamiAdminPassword} >Initial Admin Password <Explainer
disabled explanation="It could be changed in Umami. <br>This is just the password set initially after the first start."
readonly /></label
/> >
<CopyPasswordField
isPasswordField
name="umamiAdminPassword"
id="umamiAdminPassword"
placeholder="admin"
value={service.umami.umamiAdminPassword}
disabled
readonly
/>
</div>
</div> </div>

View File

@@ -8,7 +8,7 @@
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">VSCode Server</div> <div class="title">VSCode Server</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="password">{$t('forms.password')}</label> <label for="password">{$t('forms.password')}</label>
<CopyPasswordField <CopyPasswordField
id="password" id="password"

View File

@@ -7,7 +7,7 @@
<div class="title">Weblate</div> <div class="title">Weblate</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="adminPassword">Admin password</label> <label for="adminPassword">Admin password</label>
<CopyPasswordField <CopyPasswordField
name="adminPassword" name="adminPassword"
@@ -22,45 +22,46 @@
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">PostgreSQL</div> <div class="title">PostgreSQL</div>
</div> </div>
<div class="space-y-2">
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="postgresqlHost">PostgreSQL Host</label> <label for="postgresqlHost">PostgreSQL Host</label>
<CopyPasswordField <CopyPasswordField
name="postgresqlHost" name="postgresqlHost"
id="postgresqlHost" id="postgresqlHost"
value={service.weblate.postgresqlHost} value={service.weblate.postgresqlHost}
readonly readonly
disabled disabled
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="postgresqlPort">PostgreSQL Port</label> <label for="postgresqlPort">PostgreSQL Port</label>
<CopyPasswordField <CopyPasswordField
name="postgresqlPort" name="postgresqlPort"
id="postgresqlPort" id="postgresqlPort"
value={service.weblate.postgresqlPort} value={service.weblate.postgresqlPort}
readonly readonly
disabled disabled
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="postgresqlUser">PostgreSQL User</label> <label for="postgresqlUser">PostgreSQL User</label>
<CopyPasswordField <CopyPasswordField
name="postgresqlUser" name="postgresqlUser"
id="postgresqlUser" id="postgresqlUser"
value={service.weblate.postgresqlUser} value={service.weblate.postgresqlUser}
readonly readonly
disabled disabled
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="postgresqlPassword">PostgreSQL Password</label> <label for="postgresqlPassword">PostgreSQL Password</label>
<CopyPasswordField <CopyPasswordField
name="postgresqlPassword" name="postgresqlPassword"
id="postgresqlPassword" id="postgresqlPassword"
isPasswordField isPasswordField
value={service.weblate.postgresqlPassword} value={service.weblate.postgresqlPassword}
readonly readonly
disabled disabled
/> />
</div>
</div> </div>

View File

@@ -21,9 +21,7 @@
function generateUrl(publicPort: any) { function generateUrl(publicPort: any) {
return browser return browser
? `sftp://${ ? `sftp://${settings?.fqdn ? getDomain(settings.fqdn) : ipv4 || ipv6}:${publicPort}`
settings?.fqdn ? getDomain(settings.fqdn) : ipv4 || ipv6
}:${publicPort}`
: 'Loading...'; : 'Loading...';
} }
async function changeSettings(name: any) { async function changeSettings(name: any) {
@@ -72,9 +70,10 @@
<div class="title">Wordpress</div> <div class="title">Wordpress</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="extraConfig">{$t('forms.extra_config')}</label> <label for="extraConfig">{$t('forms.extra_config')}</label>
<textarea <textarea
class="w-full"
bind:value={service.wordpress.extraConfig} bind:value={service.wordpress.extraConfig}
disabled={$status.service.isRunning || $status.service.initialLoading} disabled={$status.service.isRunning || $status.service.initialLoading}
readonly={$status.service.isRunning} readonly={$status.service.isRunning}
@@ -91,7 +90,7 @@ define('SUBDOMAIN_INSTALL', false);`
: 'N/A'} : 'N/A'}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<Setting <Setting
id="ftpEnabled" id="ftpEnabled"
bind:setting={service.wordpress.ftpEnabled} bind:setting={service.wordpress.ftpEnabled}
@@ -103,15 +102,15 @@ define('SUBDOMAIN_INSTALL', false);`
/> />
</div> </div>
{#if service.wordpress.ftpEnabled} {#if service.wordpress.ftpEnabled}
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="ftpUrl">sFTP Connection URI</label> <label for="ftpUrl">sFTP Connection URI</label>
<CopyPasswordField id="ftpUrl" readonly disabled name="ftpUrl" value={ftpUrl} /> <CopyPasswordField id="ftpUrl" readonly disabled name="ftpUrl" value={ftpUrl} />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="ftpUser">User</label> <label for="ftpUser">User</label>
<CopyPasswordField id="ftpUser" readonly disabled name="ftpUser" value={ftpUser} /> <CopyPasswordField id="ftpUser" readonly disabled name="ftpUser" value={ftpUser} />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="ftpPassword">Password</label> <label for="ftpPassword">Password</label>
<CopyPasswordField <CopyPasswordField
id="ftpPassword" id="ftpPassword"
@@ -126,97 +125,104 @@ define('SUBDOMAIN_INSTALL', false);`
<div class="flex space-x-1 py-5 font-bold"> <div class="flex space-x-1 py-5 font-bold">
<div class="title">MySQL</div> <div class="title">MySQL</div>
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="space-y-2">
<Setting <div class="grid grid-cols-2 items-center lg:px-10 px-2">
id="ownMysql" <Setting
dataTooltip={$t('forms.must_be_stopped_to_modify')} id="ownMysql"
bind:setting={service.wordpress.ownMysql} dataTooltip={$t('forms.must_be_stopped_to_modify')}
disabled={$status.service.isRunning} bind:setting={service.wordpress.ownMysql}
on:click={() => !$status.service.isRunning && changeSettings('ownMysql')}
title="Use your own MySQL server"
description="Enables the use of your own MySQL server. If you don't have one, you can use the one provided by Coolify."
/>
</div>
{#if service.wordpress.ownMysql}
<div class="grid grid-cols-2 items-center px-10">
<label for="mysqlHost">Host</label>
<input
name="mysqlHost"
id="mysqlHost"
required
readonly={$status.service.isRunning}
disabled={$status.service.isRunning} disabled={$status.service.isRunning}
bind:value={service.wordpress.mysqlHost} on:click={() => !$status.service.isRunning && changeSettings('ownMysql')}
placeholder="{$t('forms.eg')}: db.coolify.io" title="Use your own MySQL server"
description="Enables the use of your own MySQL server. If you don't have one, you can use the one provided by Coolify."
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> {#if service.wordpress.ownMysql}
<label for="mysqlPort">Port</label> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="mysqlHost">Host</label>
<input
class="w-full"
name="mysqlHost"
id="mysqlHost"
required
readonly={$status.service.isRunning}
disabled={$status.service.isRunning}
bind:value={service.wordpress.mysqlHost}
placeholder="{$t('forms.eg')}: db.coolify.io"
/>
</div>
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="mysqlPort">Port</label>
<input
class="w-full"
name="mysqlPort"
id="mysqlPort"
required
readonly={$status.service.isRunning}
disabled={$status.service.isRunning}
bind:value={service.wordpress.mysqlPort}
placeholder="{$t('forms.eg')}: 3306"
/>
</div>
{/if}
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="mysqlDatabase">{$t('index.database')}</label>
<input <input
name="mysqlPort" class="w-full"
id="mysqlPort" name="mysqlDatabase"
id="mysqlDatabase"
required required
readonly={$status.service.isRunning} readonly={readOnly && !service.wordpress.ownMysql}
disabled={$status.service.isRunning} disabled={readOnly && !service.wordpress.ownMysql}
bind:value={service.wordpress.mysqlPort} bind:value={service.wordpress.mysqlDatabase}
placeholder="{$t('forms.eg')}: 3306" placeholder="{$t('forms.eg')}: wordpress_db"
/> />
</div> </div>
{/if} {#if !service.wordpress.ownMysql}
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="mysqlDatabase">{$t('index.database')}</label> <label for="mysqlRootUser">{$t('forms.root_user')}</label>
<input <input
name="mysqlDatabase" class="w-full"
id="mysqlDatabase" name="mysqlRootUser"
required id="mysqlRootUser"
readonly={readOnly && !service.wordpress.ownMysql} placeholder="MySQL {$t('forms.root_user')}"
disabled={readOnly && !service.wordpress.ownMysql} value={service.wordpress.mysqlRootUser}
bind:value={service.wordpress.mysqlDatabase} readonly={$status.service.isRunning || !service.wordpress.ownMysql}
placeholder="{$t('forms.eg')}: wordpress_db" disabled={$status.service.isRunning || !service.wordpress.ownMysql}
/> />
</div> </div>
{#if !service.wordpress.ownMysql} <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<div class="grid grid-cols-2 items-center px-10"> <label for="mysqlRootUserPassword">{$t('forms.roots_password')}</label>
<label for="mysqlRootUser">{$t('forms.root_user')}</label> <CopyPasswordField
id="mysqlRootUserPassword"
isPasswordField
readonly={$status.service.isRunning || !service.wordpress.ownMysql}
disabled={$status.service.isRunning || !service.wordpress.ownMysql}
name="mysqlRootUserPassword"
value={service.wordpress.mysqlRootUserPassword}
/>
</div>
{/if}
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="mysqlUser">{$t('forms.user')}</label>
<input <input
name="mysqlRootUser" class="w-full"
id="mysqlRootUser" name="mysqlUser"
placeholder="MySQL {$t('forms.root_user')}" id="mysqlUser"
value={service.wordpress.mysqlRootUser} bind:value={service.wordpress.mysqlUser}
readonly={$status.service.isRunning || !service.wordpress.ownMysql} readonly={$status.service.isRunning || !service.wordpress.ownMysql}
disabled={$status.service.isRunning || !service.wordpress.ownMysql} disabled={$status.service.isRunning || !service.wordpress.ownMysql}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center px-10"> <div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="mysqlRootUserPassword">{$t('forms.roots_password')}</label> <label for="mysqlPassword">{$t('forms.password')}</label>
<CopyPasswordField <CopyPasswordField
id="mysqlRootUserPassword" id="mysqlPassword"
isPasswordField isPasswordField
readonly={$status.service.isRunning || !service.wordpress.ownMysql} readonly={$status.service.isRunning || !service.wordpress.ownMysql}
disabled={$status.service.isRunning || !service.wordpress.ownMysql} disabled={$status.service.isRunning || !service.wordpress.ownMysql}
name="mysqlRootUserPassword" name="mysqlPassword"
value={service.wordpress.mysqlRootUserPassword} bind:value={service.wordpress.mysqlPassword}
/> />
</div> </div>
{/if}
<div class="grid grid-cols-2 items-center px-10">
<label for="mysqlUser">{$t('forms.user')}</label>
<input
name="mysqlUser"
id="mysqlUser"
bind:value={service.wordpress.mysqlUser}
readonly={$status.service.isRunning || !service.wordpress.ownMysql}
disabled={$status.service.isRunning || !service.wordpress.ownMysql}
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="mysqlPassword">{$t('forms.password')}</label>
<CopyPasswordField
id="mysqlPassword"
isPasswordField
readonly={$status.service.isRunning || !service.wordpress.ownMysql}
disabled={$status.service.isRunning || !service.wordpress.ownMysql}
name="mysqlPassword"
bind:value={service.wordpress.mysqlPassword}
/>
</div> </div>

View File

@@ -56,7 +56,6 @@
import { page } from '$app/stores'; import { page } from '$app/stores';
import DeleteIcon from '$lib/components/DeleteIcon.svelte'; import DeleteIcon from '$lib/components/DeleteIcon.svelte';
import { del, get, post } from '$lib/api'; import { del, get, post } from '$lib/api';
import { goto } from '$app/navigation';
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import { errorNotification, handlerNotFoundLoad } from '$lib/common'; import { errorNotification, handlerNotFoundLoad } from '$lib/common';
import { import {
@@ -69,6 +68,8 @@
} from '$lib/store'; } from '$lib/store';
import { onDestroy, onMount } from 'svelte'; import { onDestroy, onMount } from 'svelte';
import Tooltip from '$lib/components/Tooltip.svelte'; import Tooltip from '$lib/components/Tooltip.svelte';
import ServiceLinks from './_ServiceLinks.svelte';
import { goto } from '$app/navigation';
const { id } = $page.params; const { id } = $page.params;
export let service: any; export let service: any;
@@ -85,7 +86,7 @@
if (service.type && $status.service.isRunning) if (service.type && $status.service.isRunning)
await post(`/services/${service.id}/${service.type}/stop`, {}); await post(`/services/${service.id}/${service.type}/stop`, {});
await del(`/services/${service.id}`, { id: service.id }); await del(`/services/${service.id}`, { id: service.id });
return await window.location.assign(`/`); return await goto('/');
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} finally { } finally {
@@ -155,144 +156,38 @@
}); });
</script> </script>
<nav class="nav-side"> <nav class="header lg:flex-row flex-col-reverse">
{#if $location} <div class="flex flex-row space-x-2 font-bold pt-10 lg:pt-0">
<a <div class="flex flex-col items-center justify-center">
id="open" <div class="title">
href={$location} {#if $page.url.pathname === `/services/${id}`}
target="_blank" Configurations
class="icons flex items-center bg-transparent text-sm" {:else if $page.url.pathname === `/services/${id}/secrets`}
><svg Secrets
xmlns="http://www.w3.org/2000/svg" {:else if $page.url.pathname === `/services/${id}/storages`}
class="h-6 w-6" Persistent Storages
viewBox="0 0 24 24" {:else if $page.url.pathname === `/services/${id}/logs`}
stroke-width="1.5" Service Logs
stroke="currentColor" {:else if $page.url.pathname === `/services/${id}/configuration/type`}
fill="none" Select a Service Type
stroke-linecap="round" {:else if $page.url.pathname === `/services/${id}/configuration/version`}
stroke-linejoin="round" Select a Service Version
> {:else if $page.url.pathname === `/services/${id}/configuration/destination`}
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> Select a Destination
<path d="M11 7h-5a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-5" /> {/if}
<line x1="10" y1="14" x2="20" y2="4" /> </div>
<polyline points="15 4 20 4 20 9" /> </div>
</svg></a <ServiceLinks {service} />
> </div>
<Tooltip triggeredBy="#open">Open</Tooltip> <div class="lg:block hidden flex-1" />
<div class="border border-stone-700 h-8" /> <div class="flex flex-row flex-wrap space-x-3 justify-center lg:justify-start lg:py-0">
{/if} {#if $location}
{#if $status.service.isExited} <a
<a id="open"
id="error" href={$location}
href={$isDeploymentEnabled ? `/services/${id}/logs` : null} target="_blank"
class="icons bg-transparent text-sm flex items-center text-red-500 tooltip-error" class="icons flex items-center bg-transparent text-sm"
sveltekit:prefetch ><svg
>
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path
d="M8.7 3h6.6c.3 0 .5 .1 .7 .3l4.7 4.7c.2 .2 .3 .4 .3 .7v6.6c0 .3 -.1 .5 -.3 .7l-4.7 4.7c-.2 .2 -.4 .3 -.7 .3h-6.6c-.3 0 -.5 -.1 -.7 -.3l-4.7 -4.7c-.2 -.2 -.3 -.4 -.3 -.7v-6.6c0 -.3 .1 -.5 .3 -.7l4.7 -4.7c.2 -.2 .4 -.3 .7 -.3z"
/>
<line x1="12" y1="8" x2="12" y2="12" />
<line x1="12" y1="16" x2="12.01" y2="16" />
</svg>
</a>
<Tooltip triggeredBy="#error">Service exited with an error!</Tooltip>
{/if}
{#if $status.service.initialLoading}
<button
class="icons flex animate-spin items-center space-x-2 bg-transparent text-sm duration-500 ease-in-out"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-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 4.55a8 8 0 0 1 6 14.9m0 -4.45v5h5" />
<line x1="5.63" y1="7.16" x2="5.63" y2="7.17" />
<line x1="4.06" y1="11" x2="4.06" y2="11.01" />
<line x1="4.63" y1="15.1" x2="4.63" y2="15.11" />
<line x1="7.16" y1="18.37" x2="7.16" y2="18.38" />
<line x1="11" y1="19.94" x2="11" y2="19.95" />
</svg>
</button>
{:else if $status.service.isRunning}
<button
id="stop"
on:click={stopService}
type="submit"
disabled={!$isDeploymentEnabled}
class="icons bg-transparent text-sm flex items-center space-x-2 text-red-500"
>
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<rect x="6" y="5" width="4" height="14" rx="1" />
<rect x="14" y="5" width="4" height="14" rx="1" />
</svg>
</button>
<Tooltip triggeredBy="#stop">Stop</Tooltip>
{:else}
<button
id="start"
on:click={startService}
type="submit"
disabled={!$isDeploymentEnabled}
class="icons bg-transparent text-sm flex items-center space-x-2 text-green-500"
><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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M7 4v16l13 -8z" />
</svg>
</button>
<Tooltip triggeredBy="#start">Start</Tooltip>
{/if}
<div class="border border-stone-700 h-8" />
{#if service.type && service.destinationDockerId && service.version}
<a
href="/services/{id}"
sveltekit:prefetch
class="hover:text-yellow-500 rounded"
class:text-yellow-500={$page.url.pathname === `/services/${id}`}
class:bg-coolgray-500={$page.url.pathname === `/services/${id}`}
>
<button
id="configuration"
disabled={!$isDeploymentEnabled}
class="icons bg-transparent text-sm"
>
<svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6" class="h-6 w-6"
viewBox="0 0 24 24" viewBox="0 0 24 24"
@@ -303,62 +198,71 @@
stroke-linejoin="round" stroke-linejoin="round"
> >
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path stroke="none" d="M0 0h24v24H0z" fill="none" />
<rect x="4" y="8" width="4" height="4" /> <path d="M11 7h-5a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-5" />
<line x1="6" y1="4" x2="6" y2="8" /> <line x1="10" y1="14" x2="20" y2="4" />
<line x1="6" y1="12" x2="6" y2="20" /> <polyline points="15 4 20 4 20 9" />
<rect x="10" y="14" width="4" height="4" /> </svg></a
<line x1="12" y1="4" x2="12" y2="14" /> >
<line x1="12" y1="18" x2="12" y2="20" /> <Tooltip triggeredBy="#open">Open</Tooltip>
<rect x="16" y="5" width="4" height="4" /> <div class="hidden lg:block border border-coolgray-500 h-8" />
<line x1="18" y1="4" x2="18" y2="5" /> {/if}
<line x1="18" y1="9" x2="18" y2="20" /> {#if $status.service.isExited}
</svg></button <a
></a id="error"
> href={$isDeploymentEnabled ? `/services/${id}/logs` : null}
<Tooltip triggeredBy="#configuration">Configuration</Tooltip> class="icons bg-transparent text-sm flex items-center text-red-500 tooltip-error"
<a sveltekit:prefetch
href="/services/{id}/secrets"
sveltekit:prefetch
class="hover:text-pink-500 rounded"
class:text-pink-500={$page.url.pathname === `/services/${id}/secrets`}
class:bg-coolgray-500={$page.url.pathname === `/services/${id}/secrets`}
>
<button
id="secrets"
disabled={!$isDeploymentEnabled}
class="icons bg-transparent text-sm "
> >
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6" class="w-6 h-6"
viewBox="0 0 24 24" viewBox="0 0 24 24"
stroke-width="1.5" stroke-width="1.5"
stroke="currentColor" stroke="currentcolor"
fill="none" fill="none"
stroke-linecap="round" stroke-linecap="round"
stroke-linejoin="round" stroke-linejoin="round"
> >
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path <path
d="M12 3a12 12 0 0 0 8.5 3a12 12 0 0 1 -8.5 15a12 12 0 0 1 -8.5 -15a12 12 0 0 0 8.5 -3" d="M8.7 3h6.6c.3 0 .5 .1 .7 .3l4.7 4.7c.2 .2 .3 .4 .3 .7v6.6c0 .3 -.1 .5 -.3 .7l-4.7 4.7c-.2 .2 -.4 .3 -.7 .3h-6.6c-.3 0 -.5 -.1 -.7 -.3l-4.7 -4.7c-.2 -.2 -.3 -.4 -.3 -.7v-6.6c0 -.3 .1 -.5 .3 -.7l4.7 -4.7c.2 -.2 .4 -.3 .7 -.3z"
/> />
<circle cx="12" cy="11" r="1" /> <line x1="12" y1="8" x2="12" y2="12" />
<line x1="12" y1="12" x2="12" y2="14.5" /> <line x1="12" y1="16" x2="12.01" y2="16" />
</svg></button </svg>
></a </a>
> <Tooltip triggeredBy="#error">Service exited with an error!</Tooltip>
<Tooltip triggeredBy="#secrets">Secrets</Tooltip> {/if}
<a {#if $status.service.initialLoading}
href="/services/{id}/storages"
sveltekit:prefetch
class="hover:text-pink-500 rounded"
class:text-pink-500={$page.url.pathname === `/services/${id}/storages`}
class:bg-coolgray-500={$page.url.pathname === `/services/${id}/storages`}
>
<button <button
id="persistentstorage" class="icons flex animate-spin items-center space-x-2 bg-transparent text-sm duration-500 ease-in-out"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-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 4.55a8 8 0 0 1 6 14.9m0 -4.45v5h5" />
<line x1="5.63" y1="7.16" x2="5.63" y2="7.17" />
<line x1="4.06" y1="11" x2="4.06" y2="11.01" />
<line x1="4.63" y1="15.1" x2="4.63" y2="15.11" />
<line x1="7.16" y1="18.37" x2="7.16" y2="18.38" />
<line x1="11" y1="19.94" x2="11" y2="19.95" />
</svg>
</button>
{:else if $status.service.isRunning}
<button
id="stop"
on:click={stopService}
type="submit"
disabled={!$isDeploymentEnabled} disabled={!$isDeploymentEnabled}
class="icons bg-transparent text-sm" class="icons bg-transparent text-sm flex items-center space-x-2 text-red-500"
> >
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@@ -371,25 +275,21 @@
stroke-linejoin="round" stroke-linejoin="round"
> >
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path stroke="none" d="M0 0h24v24H0z" fill="none" />
<ellipse cx="12" cy="6" rx="8" ry="3" /> <rect x="6" y="5" width="4" height="14" rx="1" />
<path d="M4 6v6a8 3 0 0 0 16 0v-6" /> <rect x="14" y="5" width="4" height="14" rx="1" />
<path d="M4 12v6a8 3 0 0 0 16 0v-6" />
</svg> </svg>
</button></a </button>
> <Tooltip triggeredBy="#stop">Stop</Tooltip>
<Tooltip triggeredBy="#persistentstorage">Persistent Storage</Tooltip> {:else}
<div class="border border-stone-700 h-8" /> <button
<a id="start"
href={$isDeploymentEnabled && $status.service.isRunning ? `/services/${id}/logs` : null} on:click={startService}
sveltekit:prefetch type="submit"
class="hover:text-pink-500 rounded" disabled={!$isDeploymentEnabled}
class:text-pink-500={$page.url.pathname === `/services/${id}/logs`} class="icons bg-transparent text-sm flex items-center space-x-2 text-green-500"
class:bg-coolgray-500={$page.url.pathname === `/services/${id}/logs`} ><svg
>
<button id="logs" disabled={!$status.service.isRunning} class="icons bg-transparent text-sm">
<svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6" class="w-6 h-6"
viewBox="0 0 24 24" viewBox="0 0 24 24"
stroke-width="1.5" stroke-width="1.5"
stroke="currentColor" stroke="currentColor"
@@ -398,24 +298,152 @@
stroke-linejoin="round" stroke-linejoin="round"
> >
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M3 19a9 9 0 0 1 9 0a9 9 0 0 1 9 0" /> <path d="M7 4v16l13 -8z" />
<path d="M3 6a9 9 0 0 1 9 0a9 9 0 0 1 9 0" /> </svg>
<line x1="3" y1="6" x2="3" y2="19" /> </button>
<line x1="12" y1="6" x2="12" y2="19" /> <Tooltip triggeredBy="#start">Start</Tooltip>
<line x1="21" y1="6" x2="21" y2="19" /> {/if}
</svg></button
></a {#if service.type && service.destinationDockerId && service.version}
<div class="hidden lg:block border border-coolgray-500 h-8" />
<a
href="/services/{id}"
sveltekit:prefetch
class="hover:text-yellow-500 rounded"
class:text-yellow-500={$page.url.pathname === `/services/${id}`}
class:bg-coolgray-500={$page.url.pathname === `/services/${id}`}
>
<button
id="configuration"
disabled={!$isDeploymentEnabled}
class="icons bg-transparent text-sm"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-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" />
<rect x="4" y="8" width="4" height="4" />
<line x1="6" y1="4" x2="6" y2="8" />
<line x1="6" y1="12" x2="6" y2="20" />
<rect x="10" y="14" width="4" height="4" />
<line x1="12" y1="4" x2="12" y2="14" />
<line x1="12" y1="18" x2="12" y2="20" />
<rect x="16" y="5" width="4" height="4" />
<line x1="18" y1="4" x2="18" y2="5" />
<line x1="18" y1="9" x2="18" y2="20" />
</svg></button
></a
>
<Tooltip triggeredBy="#configuration">Configuration</Tooltip>
<a
href="/services/{id}/secrets"
sveltekit:prefetch
class="hover:text-pink-500 rounded"
class:text-pink-500={$page.url.pathname === `/services/${id}/secrets`}
class:bg-coolgray-500={$page.url.pathname === `/services/${id}/secrets`}
>
<button id="secrets" disabled={!$isDeploymentEnabled} class="icons bg-transparent text-sm ">
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path
d="M12 3a12 12 0 0 0 8.5 3a12 12 0 0 1 -8.5 15a12 12 0 0 1 -8.5 -15a12 12 0 0 0 8.5 -3"
/>
<circle cx="12" cy="11" r="1" />
<line x1="12" y1="12" x2="12" y2="14.5" />
</svg></button
></a
>
<Tooltip triggeredBy="#secrets">Secrets</Tooltip>
<a
href="/services/{id}/storages"
sveltekit:prefetch
class="hover:text-pink-500 rounded"
class:text-pink-500={$page.url.pathname === `/services/${id}/storages`}
class:bg-coolgray-500={$page.url.pathname === `/services/${id}/storages`}
>
<button
id="persistentstorage"
disabled={!$isDeploymentEnabled}
class="icons bg-transparent text-sm"
>
<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"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<ellipse cx="12" cy="6" rx="8" ry="3" />
<path d="M4 6v6a8 3 0 0 0 16 0v-6" />
<path d="M4 12v6a8 3 0 0 0 16 0v-6" />
</svg>
</button></a
>
<Tooltip triggeredBy="#persistentstorage">Persistent Storages</Tooltip>
<div class="hidden lg:block border border-coolgray-500 h-8" />
<a
href={$isDeploymentEnabled && $status.service.isRunning ? `/services/${id}/logs` : null}
sveltekit:prefetch
class="hover:text-pink-500 rounded"
class:text-pink-500={$page.url.pathname === `/services/${id}/logs`}
class:bg-coolgray-500={$page.url.pathname === `/services/${id}/logs`}
>
<button
id="logs"
disabled={!$status.service.isRunning}
class="icons bg-transparent text-sm"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-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="M3 19a9 9 0 0 1 9 0a9 9 0 0 1 9 0" />
<path d="M3 6a9 9 0 0 1 9 0a9 9 0 0 1 9 0" />
<line x1="3" y1="6" x2="3" y2="19" />
<line x1="12" y1="6" x2="12" y2="19" />
<line x1="21" y1="6" x2="21" y2="19" />
</svg></button
></a
>
<Tooltip triggeredBy="#logs">Logs</Tooltip>
{/if}
<div class="hidden lg:block border border-coolgray-500 h-8" />
<button
id="delete"
on:click={deleteService}
type="submit"
disabled={!$appSession.isAdmin}
class:hover:text-red-500={$appSession.isAdmin}
class="icons bg-transparent text-sm"><DeleteIcon /></button
> >
<Tooltip triggeredBy="#logs">Logs</Tooltip> <Tooltip triggeredBy="#delete" placement="left">Delete</Tooltip>
{/if} </div>
<button
id="delete"
on:click={deleteService}
type="submit"
disabled={!$appSession.isAdmin}
class:hover:text-red-500={$appSession.isAdmin}
class="icons bg-transparent text-sm"><DeleteIcon /></button
>
<Tooltip triggeredBy="#delete">Delete</Tooltip>
</nav> </nav>
<slot /> <slot />

View File

@@ -52,11 +52,6 @@
} }
</script> </script>
<div class="flex space-x-1 p-6 font-bold">
<div class="mr-4 text-2xl tracking-tight">
{$t('application.configuration.configure_destination')}
</div>
</div>
<div class="flex justify-center"> <div class="flex justify-center">
{#if !destinations || destinations.length === 0} {#if !destinations || destinations.length === 0}
<div class="flex-col"> <div class="flex-col">

View File

@@ -47,10 +47,6 @@
} }
</script> </script>
<div class="flex space-x-1 p-6 font-bold">
<div class="mr-4 text-2xl tracking-tight">{$t('forms.select_a_service')}</div>
</div>
<div class="flex flex-wrap justify-center"> <div class="flex flex-wrap justify-center">
{#each types as type} {#each types as type}
<div class="p-2"> <div class="p-2">

View File

@@ -57,9 +57,6 @@
} }
</script> </script>
<div class="flex space-x-1 p-6 font-bold">
<div class="mr-4 text-2xl tracking-tight">{$t('forms.select_a_service_version')}</div>
</div>
{#if from} {#if from}
<div class="pb-10 text-center"> <div class="pb-10 text-center">
Warning: you are about to change the version of this service.<br />This could cause problem Warning: you are about to change the version of this service.<br />This could cause problem

View File

@@ -50,32 +50,24 @@
}); });
</script> </script>
<div class="flex h-20 items-center space-x-2 p-5 px-6 font-bold"> {#if $status.service.isRunning}
<div class="-mb-5 flex-col"> <div class="mx-auto max-w-6xl px-6 lg:my-0 my-4 lg:pt-0 pt-4 rounded">
<div class="md:max-w-64 truncate text-base tracking-tight md:text-2xl lg:block"> <div class="text-center">
Configuration <div class="stat w-64">
</div> <div class="stat-title">Used Memory / Memory Limit</div>
<span class="text-xs">{service.name}</span> <div class="stat-value text-xl">{usage?.MemUsage}</div>
</div> </div>
<ServiceLinks {service} />
</div>
<div class="mx-auto max-w-4xl px-6 py-4">
<div class="text-2xl font-bold">Service Usage</div>
<div class="text-center">
<div class="stat w-64">
<div class="stat-title">Used Memory / Memory Limit</div>
<div class="stat-value text-xl">{usage?.MemUsage}</div>
</div>
<div class="stat w-64"> <div class="stat w-64">
<div class="stat-title">Used CPU</div> <div class="stat-title">Used CPU</div>
<div class="stat-value text-xl">{usage?.CPUPerc}</div> <div class="stat-value text-xl">{usage?.CPUPerc}</div>
</div> </div>
<div class="stat w-64"> <div class="stat w-64">
<div class="stat-title">Network IO</div> <div class="stat-title">Network IO</div>
<div class="stat-value text-xl">{usage?.NetIO}</div> <div class="stat-value text-xl">{usage?.NetIO}</div>
</div>
</div> </div>
</div> </div>
</div> {/if}
<Services bind:service bind:readOnly bind:settings /> <Services bind:service bind:readOnly bind:settings />

View File

@@ -150,16 +150,10 @@
</button> </button>
<Tooltip triggeredBy="#follow">Follow Logs</Tooltip> <Tooltip triggeredBy="#follow">Follow Logs</Tooltip>
</div> </div>
<div <div class="font-mono w-full rounder bg-coolgray-200 p-5 overflow-x-auto overflox-y-auto max-h-[80vh] rounded-md mb-20 flex flex-col whitespace-nowrap -mt-12 scrollbar-thumb-coollabs scrollbar-track-coolgray-200 scrollbar-w-1">
class="font-mono w-full leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12 overflow-y-scroll scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200" {#each logs as log}
bind:this={logsEl} <p>{log.line + '\n'}</p>
on:scroll={detect} {/each}
>
<div class="px-2 pr-14">
{#each logs as log}
{log + '\n'}
{/each}
</div>
</div> </div>
</div> </div>
{/if} {/if}

View File

@@ -68,64 +68,33 @@
} }
</script> </script>
<div
class="flex items-center space-x-2 p-5 px-6 font-bold"
class:p-5={service.fqdn}
class:p-6={!service.fqdn}
>
<div class="-mb-5 flex-col">
<div class="md:max-w-64 truncate text-base tracking-tight md:text-2xl lg:block">
{$t('application.secret')}
</div>
<span class="text-xs">{service.name}</span>
</div>
{#if service.fqdn}
<a
href={service.fqdn}
target="_blank"
class="icons tooltip-bottom flex items-center bg-transparent text-sm"
><svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-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="M11 7h-5a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-5" />
<line x1="10" y1="14" x2="20" y2="4" />
<polyline points="15 4 20 4 20 9" />
</svg></a
>
{/if}
<ServiceLinks {service} />
</div>
<div class="mx-auto max-w-6xl rounded-xl px-6 pt-4"> <div class="mx-auto max-w-6xl rounded-xl px-6 pt-4">
<table class="mx-auto border-separate text-left"> <h1 class="md:max-w-64 truncate text-base tracking-tight md:text-2xl lg:block font-bold mb-4">
<thead> Secrets
<tr class="h-12"> </h1>
<th scope="col">{$t('forms.name')}</th> <div class="overflow-x-auto">
<th scope="col">{$t('forms.value')}</th> <table class="w-full border-separate text-left">
<th scope="col" class="w-96 text-center">{$t('forms.action')}</th> <thead>
</tr> <tr class="h-12">
</thead> <th scope="col">{$t('forms.name')}</th>
<tbody> <th scope="col">{$t('forms.value')}</th>
{#each secrets as secret} <th scope="col" class="w-96 text-center">{$t('forms.action')}</th>
{#key secret.id} </tr>
<tr> </thead>
<Secret name={secret.name} value={secret.value} on:refresh={refreshSecrets} /> <tbody>
</tr> {#each secrets as secret}
{/key} {#key secret.id}
{/each} <tr>
<tr> <Secret name={secret.name} value={secret.value} on:refresh={refreshSecrets} />
<Secret isNewSecret on:refresh={refreshSecrets} /> </tr>
</tr> {/key}
</tbody> {/each}
</table> <tr>
<Secret isNewSecret on:refresh={refreshSecrets} />
</tr>
</tbody>
</table>
</div>
<h2 class="title my-6 font-bold">Paste .env file</h2> <h2 class="title my-6 font-bold">Paste .env file</h2>
<form on:submit|preventDefault={getValues} class="mb-12 w-full"> <form on:submit|preventDefault={getValues} class="mb-12 w-full">
<textarea bind:value={batchSecrets} class="mb-2 min-h-[200px] w-full" /> <textarea bind:value={batchSecrets} class="mb-2 min-h-[200px] w-full" />

View File

@@ -43,28 +43,26 @@
}); });
</script> </script>
<div class="flex space-x-1 p-6 font-bold"> <nav class="header">
<div class="mr-4 text-2xl tracking-tight">{$t('index.services')}</div> <h1 class="mr-4 text-2xl font-bold">{$t('index.services')}</h1>
{#if $appSession.isAdmin} <button on:click={newService} class="btn btn-square btn-sm bg-services">
<button on:click={newService} class="btn btn-square btn-sm bg-services"> <svg
<svg class="h-6 w-6"
class="h-6 w-6" xmlns="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" fill="none"
fill="none" viewBox="0 0 24 24"
viewBox="0 0 24 24" stroke="currentColor"
stroke="currentColor" ><path
><path stroke-linecap="round"
stroke-linecap="round" stroke-linejoin="round"
stroke-linejoin="round" stroke-width="2"
stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"
d="M12 6v6m0 0v6m0-6h6m-6 0H6" /></svg
/></svg >
> </button>
</button> </nav>
{/if} <br />
</div> <div class="flex-col justify-center mt-10 pb-12 sm:pb-16 lg:pt-16">
<div class="flex-col justify-center mt-10 pb-12 sm:pb-16">
{#if !services || ownServices.length === 0} {#if !services || ownServices.length === 0}
<div class="flex-col"> <div class="flex-col">
<div class="text-center text-xl font-bold">{$t('service.no_service')}</div> <div class="text-center text-xl font-bold">{$t('service.no_service')}</div>

View File

@@ -7,7 +7,7 @@
{#if $appSession.teamId === '0'} {#if $appSession.teamId === '0'}
<a <a
href="/settings/global" href="/settings/global"
class="sub-menu no-underline" class="sub-menu no-underline w-full"
class:sub-menu-active={$page.routeId === 'settings/global'} class:sub-menu-active={$page.routeId === 'settings/global'}
> >
Global Settings Global Settings
@@ -15,7 +15,7 @@
{/if} {/if}
<a <a
href="/settings/ssh-keys" href="/settings/ssh-keys"
class="sub-menu no-underline" class="sub-menu no-underline w-full"
class:sub-menu-active={$page.routeId === 'settings/ssh-keys'}>SSH Keys</a class:sub-menu-active={$page.routeId === 'settings/ssh-keys'}>SSH Keys</a
> >
</div> </div>

View File

@@ -198,171 +198,152 @@
<div class="mr-4 text-2xl tracking-tight">{$t('index.settings')}</div> <div class="mr-4 text-2xl tracking-tight">{$t('index.settings')}</div>
</div> </div>
<div class="mx-auto w-full"> <div class="mx-auto w-full">
<div class="flex flex-row"> <div class="flex lg:flex-row flex-col">
<Menu /> <Menu />
<div> <div class="mt-5">
<form on:submit|preventDefault={handleSubmit} class="grid grid-flow-row gap-2 py-4"> <form on:submit|preventDefault={handleSubmit}>
<div class="flex space-x-1 pb-6"> <div
class="flex flex-col space-y-2 p-6 lg:p-0 lg:flex-row lg:space-y0 lg:space-x-4 w-full lg:justify-between lg:items-center mb-5"
>
<div class="title font-bold">{$t('index.global_settings')}</div> <div class="title font-bold">{$t('index.global_settings')}</div>
<button <div class="flex lg:flex-row lg:space-x-4 flex-col space-y-2 lg:space-y-0">
class="btn btn-sm bg-settings text-black"
type="submit"
class:bg-orange-600={forceSave}
class:hover:bg-orange-400={forceSave}
disabled={loading.save}
>{loading.save
? $t('forms.saving')
: forceSave
? $t('forms.confirm_continue')
: $t('forms.save')}</button
>
{#if isFqdnSet}
<button <button
on:click|preventDefault={removeFqdn} class="btn btn-sm bg-settings text-black"
disabled={loading.remove} type="submit"
class="btn btn-sm" class:bg-orange-600={forceSave}
>{loading.remove ? $t('forms.removing') : $t('forms.remove_domain')}</button class:hover:bg-orange-400={forceSave}
disabled={loading.save}
>{loading.save
? $t('forms.saving')
: forceSave
? $t('forms.confirm_continue')
: $t('forms.save')}</button
> >
{/if}
<button
on:click={restartCoolify}
class:loading={loading.restart}
class="btn btn-sm bg-red-600 hover:bg-red-500">Restart Coolify</button
>
</div>
<div class="grid grid-flow-row gap-2 px-10">
<!-- <Language /> -->
<div class="grid grid-cols-2 items-start">
<div class="flex-col">
<div class="pt-2 text-base font-bold text-stone-100">
{$t('application.url_fqdn')}
<Explainer explanation={$t('setting.ssl_explainer')} />
</div>
</div>
<div class="justify-start text-left">
<input
bind:value={fqdn}
readonly={!$appSession.isAdmin || isFqdnSet}
disabled={!$appSession.isAdmin || isFqdnSet}
on:input={resetView}
name="fqdn"
id="fqdn"
pattern="^https?://([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{'{'}2,{'}'}$"
placeholder="{$t('forms.eg')}: https://coolify.io"
/>
{#if forceSave} {#if isFqdnSet}
<div class="flex-col space-y-2 pt-4 text-center"> <button
{#if isNonWWWDomainOK} on:click|preventDefault={removeFqdn}
<button disabled={loading.remove}
class="btn btn-sm bg-success" class="btn btn-sm"
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)} >{loading.remove ? $t('forms.removing') : $t('forms.remove_domain')}</button
>DNS settings for {nonWWWDomain} is OK, click to recheck.</button >
> {/if}
{:else} <button
<button on:click={restartCoolify}
class="btn btn-sm bg-error" class:loading={loading.restart}
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)} class="btn btn-sm bg-red-600 hover:bg-red-500">Restart Coolify</button
>DNS settings for {nonWWWDomain} is invalid, click to recheck.</button >
> </div>
{/if} </div>
{#if dualCerts} <div class="grid gap-4 grid-cols-2 auto-rows-max lg:px-10 p-6">
{#if isWWWDomainOK} <div class="pt-2 text-base font-bold text-stone-100">
<button {$t('application.url_fqdn')}
class="btn btn-sm bg-success" <Explainer explanation={$t('setting.ssl_explainer')} />
on:click|preventDefault={() => </div>
isDNSValid(getDomain(`www.${nonWWWDomain}`), true)} <input
>DNS settings for www.{nonWWWDomain} is OK, click to recheck.</button class="w-full"
> bind:value={fqdn}
{:else} readonly={!$appSession.isAdmin || isFqdnSet}
<button disabled={!$appSession.isAdmin || isFqdnSet}
class="btn btn-sm bg-error" on:input={resetView}
on:click|preventDefault={() => name="fqdn"
isDNSValid(getDomain(`www.${nonWWWDomain}`), true)} id="fqdn"
>DNS settings for www.{nonWWWDomain} is invalid, click to recheck.</button pattern="^https?://([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{'{'}2,{'}'}$"
> placeholder="{$t('forms.eg')}: https://coolify.io"
{/if} />
{/if}
</div> {#if forceSave}
<div class="flex-col space-y-2 pt-4 text-center">
{#if isNonWWWDomainOK}
<button
class="btn btn-sm bg-success"
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)}
>DNS settings for {nonWWWDomain} is OK, click to recheck.</button
>
{:else}
<button
class="btn btn-sm bg-error"
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)}
>DNS settings for {nonWWWDomain} is invalid, click to recheck.</button
>
{/if}
{#if dualCerts}
{#if isWWWDomainOK}
<button
class="btn btn-sm bg-success"
on:click|preventDefault={() =>
isDNSValid(getDomain(`www.${nonWWWDomain}`), true)}
>DNS settings for www.{nonWWWDomain} is OK, click to recheck.</button
>
{:else}
<button
class="btn btn-sm bg-error"
on:click|preventDefault={() =>
isDNSValid(getDomain(`www.${nonWWWDomain}`), true)}
>DNS settings for www.{nonWWWDomain} is invalid, click to recheck.</button
>
{/if}
{/if} {/if}
</div> </div>
{/if}
<div class="pt-2 text-base font-bold text-stone-100">
{$t('forms.public_port_range')}
<Explainer explanation={$t('forms.public_port_range_explainer')} />
</div> </div>
<div class="grid grid-cols-2 items-start py-6"> <div class="flex flex-row items-center space-x-2">
<div class="flex-col"> <input
<div class="pt-2 text-base font-bold text-stone-100"> class="h-8 w-full px-2"
{$t('forms.public_port_range')} type="number"
<Explainer explanation={$t('forms.public_port_range_explainer')} /> bind:value={minPort}
</div> min="1024"
</div> max={maxPort}
<div class="mx-auto flex-row items-center justify-center space-y-2"> />
<input <p>-</p>
class="h-8 w-20 px-2" <input
type="number" class="h-8 w-full px-2"
bind:value={minPort} type="number"
min="1024" bind:value={maxPort}
max={maxPort} min={minPort}
/> max="65543"
-
<input
class="h-8 w-20 px-2"
type="number"
bind:value={maxPort}
min={minPort}
max="65543"
/>
</div>
</div>
<div class="grid grid-cols-2 items-center">
<Setting
id="isDNSCheckEnabled"
bind:setting={isDNSCheckEnabled}
title={$t('setting.is_dns_check_enabled')}
description={$t('setting.is_dns_check_enabled_explainer')}
on:click={() => changeSettings('isDNSCheckEnabled')}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <Setting
<div class="text-base font-bold text-stone-100"> id="isDNSCheckEnabled"
Custom DNS servers <Explainer bind:setting={isDNSCheckEnabled}
explanation="You can specify a custom DNS server to verify your domains all over Coolify.<br><br>By default, the OS defined DNS servers are used." title={$t('setting.is_dns_check_enabled')}
/> description={$t('setting.is_dns_check_enabled_explainer')}
</div> on:click={() => changeSettings('isDNSCheckEnabled')}
/>
<div class="flex-row items-center justify-center"> <div class="text-base font-bold text-stone-100">
<input placeholder="1.1.1.1,8.8.8.8" bind:value={DNSServers} /> Custom DNS servers <Explainer
</div> explanation="You can specify a custom DNS server to verify your domains all over Coolify.<br><br>By default, the OS defined DNS servers are used."
</div>
<div class="grid grid-cols-2 items-center">
<Setting
id="dualCerts"
dataTooltip={$t('setting.must_remove_domain_before_changing')}
disabled={isFqdnSet}
bind:setting={dualCerts}
title={$t('application.ssl_www_and_non_www')}
description={$t('setting.generate_www_non_www_ssl')}
on:click={() => !isFqdnSet && changeSettings('dualCerts')}
/> />
</div> </div>
<div class="grid grid-cols-2 items-center"> <input class="w-full" placeholder="1.1.1.1,8.8.8.8" bind:value={DNSServers} />
<Setting <Setting
id="isRegistrationEnabled" id="dualCerts"
bind:setting={isRegistrationEnabled} dataTooltip={$t('setting.must_remove_domain_before_changing')}
title={$t('setting.registration_allowed')} disabled={isFqdnSet}
description={$t('setting.registration_allowed_explainer')} bind:setting={dualCerts}
on:click={() => changeSettings('isRegistrationEnabled')} title={$t('application.ssl_www_and_non_www')}
/> description={$t('setting.generate_www_non_www_ssl')}
</div> on:click={() => !isFqdnSet && changeSettings('dualCerts')}
<div class="grid grid-cols-2 items-center"> />
<Setting <Setting
id="isAPIDebuggingEnabled" id="isRegistrationEnabled"
bind:setting={isAPIDebuggingEnabled} bind:setting={isRegistrationEnabled}
title="API Debugging" title={$t('setting.registration_allowed')}
description="Enable API debugging. This will log all API requests and responses.<br><br>You need to restart the Coolify for this to take effect." description={$t('setting.registration_allowed_explainer')}
on:click={() => changeSettings('isAPIDebuggingEnabled')} on:click={() => changeSettings('isRegistrationEnabled')}
/> />
</div> <Setting
<div class="grid grid-cols-2 items-center"> id="isAPIDebuggingEnabled"
bind:setting={isAPIDebuggingEnabled}
title="API Debugging"
description="Enable API debugging. This will log all API requests and responses.<br><br>You need to restart the Coolify for this to take effect."
on:click={() => changeSettings('isAPIDebuggingEnabled')}
/>
{#if browser && $features.beta}
<Setting <Setting
id="isAutoUpdateEnabled" id="isAutoUpdateEnabled"
bind:setting={isAutoUpdateEnabled} bind:setting={isAutoUpdateEnabled}
@@ -370,7 +351,7 @@
description={$t('setting.auto_update_enabled_explainer')} description={$t('setting.auto_update_enabled_explainer')}
on:click={() => changeSettings('isAutoUpdateEnabled')} on:click={() => changeSettings('isAutoUpdateEnabled')}
/> />
</div> {/if}
</div> </div>
</form> </form>
</div> </div>

View File

@@ -61,10 +61,13 @@
<div class="mr-4 text-2xl tracking-tight">{$t('index.settings')}</div> <div class="mr-4 text-2xl tracking-tight">{$t('index.settings')}</div>
</div> </div>
<div class="mx-auto w-full"> <div class="mx-auto w-full">
<div class="flex flex-row"> <div class="flex lg:flex-row flex-col">
<Menu /> <Menu />
<div class="grid grid-flow-row gap-2 py-4"> <div class="flex flex-col mt-5">
<div class="flex space-x-1 pb-6"> <div
class="flex flex-col space-y-2 p-6 lg:p-0 lg:flex-row lg:space-y0 lg:space-x-4 w-full lg:justify-between lg:items-center mb-5"
style="min-width: 83vw"
>
<div class="title font-bold">SSH Keys</div> <div class="title font-bold">SSH Keys</div>
<button <button
on:click={() => (isModalActive = true)} on:click={() => (isModalActive = true)}
@@ -72,7 +75,7 @@
disabled={loading.save}>New SSH Key</button disabled={loading.save}>New SSH Key</button
> >
</div> </div>
<div class="grid grid-flow-col gap-2 px-10"> <div class="grid grid-flow-col gap-2 lg:px-10 px-6">
{#if sshKeys.length === 0} {#if sshKeys.length === 0}
<div class="text-sm ">No SSH keys found</div> <div class="text-sm ">No SSH keys found</div>
{:else} {:else}

View File

@@ -90,142 +90,123 @@
} }
</script> </script>
<div class="mx-auto max-w-4xl px-6"> <div class="mx-auto max-w-6xl lg:px-6 px-3">
{#if !source.githubAppId} {#if !source.githubAppId}
<form on:submit|preventDefault={newGithubApp} class="py-4"> <form on:submit|preventDefault={newGithubApp} class="py-4">
<div class="grid gap-1 lg:grid-flow-col pb-7"> <div class="grid gap-1 lg:grid-flow-col pb-7">
<div class="title">General</div> <h1 class="title">General</h1>
{#if !source.githubAppId} {#if !source.githubAppId}
<button class="btn btn-sm bg-sources" type="submit">Save & Redirect to GitHub</button> <div class="w-full flex flex-rpw justify-end">
{/if} <button class="btn btn-sm bg-sources mt-5 w-full lg:w-fit" type="submit"
</div> >Save & Redirect to GitHub</button
<div class="grid grid-flow-row gap-2 px-10">
<div class="grid grid-flow-row gap-2">
<div class="mt-2 grid lg:grid-cols-2 items-center">
<label for="name" class="text-base font-bold text-stone-100">Name</label>
<input name="name" id="name" required bind:value={source.name} />
</div>
</div>
<div class="grid lg:grid-cols-2 items-center">
<label for="htmlUrl" class="text-base font-bold text-stone-100">HTML URL</label>
<input name="htmlUrl" id="htmlUrl" required bind:value={source.htmlUrl} />
</div>
<div class="grid lg:grid-cols-2 items-center">
<label for="apiUrl" class="text-base font-bold text-stone-100">API URL</label>
<input name="apiUrl" id="apiUrl" required bind:value={source.apiUrl} />
</div>
<div class="grid lg:grid-cols-2 items-center">
<label for="customPort" class="text-base font-bold text-stone-100"
>Custom SSH Port <Explainer
explanation={'If you use a self-hosted version of Git, you can provide custom port for all the Git related actions.'}
/></label
>
<input
name="customPort"
id="customPort"
disabled={!selfHosted || source.githubAppId}
readonly={!selfHosted || source.githubAppId}
required
value={source.customPort}
/>
</div>
<div class="grid lg:grid-cols-2">
<div class="flex flex-col">
<label for="organization" class="pt-2 text-base font-bold text-stone-100"
>Organization
<Explainer
explanation={"Fill it if you would like to use an organization's as your Git Source. Otherwise your user will be used."}
/></label
> >
</div> </div>
<input {/if}
name="organization" </div>
id="organization" <div class="grid gap-4 grid-cols-2 auto-rows-max">
placeholder="eg: coollabsio" <label for="name" class="text-base font-bold text-stone-100">Name</label>
bind:value={source.organization} <input class="w-full" name="name" id="name" required bind:value={source.name} />
/> <label for="htmlUrl" class="text-base font-bold text-stone-100">HTML URL</label>
</div> <input class="w-full" name="htmlUrl" id="htmlUrl" required bind:value={source.htmlUrl} />
<label for="apiUrl" class="text-base font-bold text-stone-100">API URL</label>
<input class="w-full" name="apiUrl" id="apiUrl" required bind:value={source.apiUrl} />
<label for="customPort" class="text-base font-bold text-stone-100"
>Custom SSH Port <Explainer
explanation={'If you use a self-hosted version of Git, you can provide custom port for all the Git related actions.'}
/></label
>
<input
class="w-full"
name="customPort"
id="customPort"
disabled={!selfHosted || source.githubAppId}
readonly={!selfHosted || source.githubAppId}
required
value={source.customPort}
/>
<label for="organization" class="pt-2 text-base font-bold text-stone-100"
>Organization
<Explainer
explanation={"Fill it if you would like to use an organization's as your Git Source. Otherwise your user will be used."}
/></label
>
<input
class="w-full"
name="organization"
id="organization"
placeholder="eg: coollabsio"
bind:value={source.organization}
/>
</div> </div>
</form> </form>
{:else if source.githubApp?.installationId} {:else if source.githubApp?.installationId}
<form on:submit|preventDefault={handleSubmit} class="py-4"> <form on:submit|preventDefault={handleSubmit} class="py-4">
<div class="flex md:flex-row space-y-2 md:space-y-0 space-x-0 md:space-x-2 flex-col pb-5"> <div class="flex lg:flex-row lg:justify-between flex-col space-y-3 w-full lg:items-center">
<div class="title">{$t('general')}</div> <h1 class="title">{$t('general')}</h1>
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<button class="btn btn-sm bg-sources" type="submit" disabled={loading} <div class="flex flex-col lg:flex-row lg:space-x-4 lg:w-fit space-y-2 lg:space-y-0 w-full">
>{loading ? 'Saving...' : 'Save'}</button <button class="btn btn-sm bg-sources" type="submit" disabled={loading}
> >{loading ? 'Saving...' : 'Save'}</button
<a >
class="btn btn-sm" <a
href={`${source.htmlUrl}/${ class="btn btn-sm"
source.htmlUrl === 'https://github.com' ? 'apps' : 'github-apps' href={`${source.htmlUrl}/${
}/${source.githubApp.name}/installations/new`} source.htmlUrl === 'https://github.com' ? 'apps' : 'github-apps'
>{$t('source.change_app_settings', { name: 'GitHub' })}</a }/${source.githubApp.name}/installations/new`}
> >{$t('source.change_app_settings', { name: 'GitHub' })}</a
>
</div>
{/if} {/if}
</div> </div>
<div class="grid grid-flow-row gap-2 px-10"> <div class="grid gap-4 grid-cols-2 auto-rows-max mt-4">
<div class="grid grid-flow-row gap-2"> <label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label>
<div class="mt-2 grid lg:grid-cols-2 items-center"> <input class="w-full" name="name" id="name" required bind:value={source.name} />
<label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label> <label for="htmlUrl" class="text-base font-bold text-stone-100">HTML URL</label>
<input name="name" id="name" required bind:value={source.name} /> <input
</div> class="w-full"
</div> name="htmlUrl"
<div class="grid lg:grid-cols-2 items-center"> id="htmlUrl"
<label for="htmlUrl" class="text-base font-bold text-stone-100">HTML URL</label> disabled={source.githubAppId}
<input readonly={source.githubAppId}
name="htmlUrl" required
id="htmlUrl" bind:value={source.htmlUrl}
disabled={source.githubAppId} />
readonly={source.githubAppId} <label for="apiUrl" class="text-base font-bold text-stone-100">API URL</label>
required <input
bind:value={source.htmlUrl} class="w-full"
/> name="apiUrl"
</div> id="apiUrl"
<div class="grid lg:grid-cols-2 items-center"> required
<label for="apiUrl" class="text-base font-bold text-stone-100">API URL</label> disabled={source.githubAppId}
<input readonly={source.githubAppId}
name="apiUrl" bind:value={source.apiUrl}
id="apiUrl" />
required <label for="customPort" class="text-base font-bold text-stone-100"
disabled={source.githubAppId} >Custom SSH Port <Explainer
readonly={source.githubAppId} explanation="If you use a self-hosted version of Git, you can provide custom port for all the Git related actions."
bind:value={source.apiUrl} /></label
/> >
</div> <input
{#if selfHosted} class="w-full"
<div class="grid lg:grid-cols-2 items-center"> name="customPort"
<label for="customPort" class="text-base font-bold text-stone-100" id="customPort"
>Custom SSH Port <Explainer disabled={!selfHosted}
explanation="If you use a self-hosted version of Git, you can provide custom port for all the Git related actions." readonly={!selfHosted}
/></label required
> value={source.customPort}
<input />
name="customPort" <label for="organization" class="pt-2 text-base font-bold text-stone-100"
id="customPort" >Organization</label
disabled={!selfHosted} >
readonly={!selfHosted} <input
required class="w-full"
value={source.customPort} readonly
/> disabled
</div> name="organization"
{/if} id="organization"
<div class="grid lg:grid-cols-2"> placeholder="eg: coollabsio"
<div class="flex flex-col"> bind:value={source.organization}
<label for="organization" class="pt-2 text-base font-bold text-stone-100" />
>Organization</label
>
</div>
<input
readonly
disabled
name="organization"
id="organization"
placeholder="eg: coollabsio"
bind:value={source.organization}
/>
</div>
</div> </div>
</form> </form>
{:else} {:else}

View File

@@ -143,26 +143,28 @@
} }
</script> </script>
<div class="mx-auto max-w-4xl px-6"> <div class="mx-auto max-w-6xl px-6">
<form on:submit|preventDefault={handleSubmit} class="py-4"> <form on:submit|preventDefault={handleSubmit} class="py-4">
<div class="flex space-x-1 pb-7"> <div class="flex lg:flex-row lg:justify-between flex-col space-y-3 w-full lg:items-center">
<div class="title">General</div> <h1 class="title">General</h1>
{#if $appSession.isAdmin} <div class="flex flex-col lg:flex-row lg:space-x-4 lg:w-fit space-y-2 lg:space-y-0 w-full">
<button type="submit" class="btn btn-sm bg-sources" disabled={loading} {#if $appSession.isAdmin}
>{loading ? $t('forms.saving') : $t('forms.save')}</button <button type="submit" class="btn btn-sm bg-sources" disabled={loading}
> >{loading ? $t('forms.saving') : $t('forms.save')}</button
{#if source.gitlabAppId}
<button class="btn btn-sm" on:click|preventDefault={changeSettings}
>{$t('source.change_app_settings', { name: 'GitLab' })}</button
>
{:else}
<button class="btn btn-sm" on:click|preventDefault|stopPropagation={newApp}
>Create new GitLab App manually</button
> >
{#if source.gitlabAppId}
<button class="btn btn-sm" on:click|preventDefault={changeSettings}
>{$t('source.change_app_settings', { name: 'GitLab' })}</button
>
{:else}
<button class="btn btn-sm" on:click|preventDefault|stopPropagation={newApp}
>Create new GitLab App manually</button
>
{/if}
{/if} {/if}
{/if} </div>
</div> </div>
<div class="grid grid-flow-row gap-2 px-10"> <div class="grid grid-flow-row gap-2 lg:px-10">
{#if !source.gitlabAppId} {#if !source.gitlabAppId}
<a <a
href="https://docs.coollabs.io/coolify/sources#how-to-integrate-with-gitlab" href="https://docs.coollabs.io/coolify/sources#how-to-integrate-with-gitlab"
@@ -172,7 +174,7 @@
> >
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="type" class="text-base font-bold text-stone-100">Application Type</label> <label for="type" class="text-base font-bold text-stone-100">Application Type</label>
<select name="type" id="type" class="w-96" bind:value={applicationType}> <select name="type" id="type" class="lg:w-96 w-full" bind:value={applicationType}>
<option value="user">{$t('source.gitlab.user_owned')}</option> <option value="user">{$t('source.gitlab.user_owned')}</option>
<option value="group">{$t('source.gitlab.group_owned')}</option> <option value="group">{$t('source.gitlab.group_owned')}</option>
{#if source.htmlUrl !== 'https://gitlab.com'} {#if source.htmlUrl !== 'https://gitlab.com'}
@@ -185,6 +187,7 @@
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="groupName" class="text-base font-bold text-stone-100">Group Name</label> <label for="groupName" class="text-base font-bold text-stone-100">Group Name</label>
<input <input
class="w-full"
name="groupName" name="groupName"
id="groupName" id="groupName"
required required
@@ -197,12 +200,29 @@
<div class="grid grid-flow-row gap-2"> <div class="grid grid-flow-row gap-2">
<div class="mt-2 grid grid-cols-2 items-center"> <div class="mt-2 grid grid-cols-2 items-center">
<label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label> <label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label>
<input name="name" id="name" required bind:value={source.name} /> <input class="w-full" name="name" id="name" required bind:value={source.name} />
</div> </div>
</div> </div>
{#if source.gitlabApp.groupName}
<div class="grid grid-cols-2 items-center">
<label for="groupName" class="text-base font-bold text-stone-100"
>{$t('source.group_name')}</label
>
<input
class="w-full"
name="groupName"
id="groupName"
disabled={source.gitlabAppId}
readonly={source.gitlabAppId}
required
bind:value={source.gitlabApp.groupName}
/>
</div>
{/if}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="htmlUrl" class="text-base font-bold text-stone-100">HTML URL</label> <label for="htmlUrl" class="text-base font-bold text-stone-100">HTML URL</label>
<input <input
class="w-full"
name="htmlUrl" name="htmlUrl"
id="htmlUrl" id="htmlUrl"
required required
@@ -214,6 +234,7 @@
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="apiUrl" class="text-base font-bold text-stone-100">API URL</label> <label for="apiUrl" class="text-base font-bold text-stone-100">API URL</label>
<input <input
class="w-full"
name="apiUrl" name="apiUrl"
id="apiUrl" id="apiUrl"
disabled={source.gitlabAppId} disabled={source.gitlabAppId}
@@ -230,6 +251,7 @@
/></label /></label
> >
<input <input
class="w-full"
name="customPort" name="customPort"
id="customPort" id="customPort"
disabled={!selfHosted} disabled={!selfHosted}
@@ -249,6 +271,7 @@
> >
</div> </div>
<input <input
class="w-full"
disabled={source.gitlabAppId} disabled={source.gitlabAppId}
readonly={source.gitlabAppId} readonly={source.gitlabAppId}
on:change={checkOauthId} on:change={checkOauthId}
@@ -266,6 +289,7 @@
>{$t('source.application_id')}</label >{$t('source.application_id')}</label
> >
<input <input
class="w-full"
name="appId" name="appId"
id="appId" id="appId"
disabled={source.gitlabAppId} disabled={source.gitlabAppId}

View File

@@ -36,8 +36,8 @@
}); });
</script> </script>
<div class="flex space-x-1 p-6 font-bold"> <nav class="header">
<div class="mr-4 text-2xl tracking-tight">{$t('index.git_sources')}</div> <h1 class="mr-4 text-2xl font-bold">{$t('index.git_sources')}</h1>
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<a href="/sources/new" class="btn btn-square btn-sm bg-sources"> <a href="/sources/new" class="btn btn-square btn-sm bg-sources">
<svg <svg
@@ -55,8 +55,9 @@
> >
</a> </a>
{/if} {/if}
</div> </nav>
<div class="flex-col justify-center mt-10 pb-12 sm:pb-16"> <br />
<div class="flex-col justify-center mt-10 pb-12 sm:pb-16 lg:pt-16">
{#if !sources || ownSources.length === 0} {#if !sources || ownSources.length === 0}
<div class="flex-col"> <div class="flex-col">
<div class="text-center text-xl font-bold">{$t('source.no_git_sources_found')}</div> <div class="text-center text-xl font-bold">{$t('source.no_git_sources_found')}</div>

View File

@@ -28,7 +28,7 @@ input, .input {
@apply h-12 w-96 rounded border border-transparent bg-transparent bg-coolgray-200 p-2 text-xs tracking-tight text-white placeholder-stone-600 outline-none transition duration-150 hover:bg-coolgray-500 focus:bg-coolgray-500 disabled:border disabled:border-dashed disabled:border-coolgray-300 disabled:bg-transparent md:text-sm; @apply h-12 w-96 rounded border border-transparent bg-transparent bg-coolgray-200 p-2 text-xs tracking-tight text-white placeholder-stone-600 outline-none transition duration-150 hover:bg-coolgray-500 focus:bg-coolgray-500 disabled:border disabled:border-dashed disabled:border-coolgray-300 disabled:bg-transparent md:text-sm;
} }
textarea { textarea {
@apply min-w-[24rem] rounded border border-transparent bg-transparent bg-coolgray-200 p-2 text-xs tracking-tight text-white placeholder-stone-600 outline-none transition duration-150 hover:bg-coolgray-500 focus:bg-coolgray-500 disabled:border disabled:border-dashed disabled:border-coolgray-300 disabled:bg-transparent md:text-sm; @apply min-w-[14rem] rounded border border-transparent bg-transparent bg-coolgray-200 p-2 text-xs tracking-tight text-white placeholder-stone-600 outline-none transition duration-150 hover:bg-coolgray-500 focus:bg-coolgray-500 disabled:border disabled:border-dashed disabled:border-coolgray-300 disabled:bg-transparent md:text-sm;
} }
#svelte .custom-select-wrapper .selectContainer.disabled input { #svelte .custom-select-wrapper .selectContainer.disabled input {
@@ -40,7 +40,7 @@ textarea {
} }
#svelte .custom-select-wrapper .selectContainer { #svelte .custom-select-wrapper .selectContainer {
@apply h-12 w-96 rounded border border-coolgray-300 border-dashed bg-coolgray-200 p-2 px-0 text-xs tracking-tight outline-none transition duration-150 hover:bg-coolgray-500 focus:bg-coolgray-500 md:text-sm; @apply h-12 w-96 rounded border border-coolgray-300 bg-coolgray-200 p-2 px-0 text-xs tracking-tight outline-none transition duration-150 hover:bg-coolgray-500 focus:bg-coolgray-500 md:text-sm w-full;
} }
#svelte .listContainer { #svelte .listContainer {
@@ -82,7 +82,7 @@ select {
} }
label { label {
@apply inline-block w-64 text-xs tracking-tight md:text-sm; @apply inline-block;
} }
.btn { .btn {
@apply text-white text-base min-w-fit; @apply text-white text-base min-w-fit;
@@ -97,7 +97,7 @@ a {
} }
.title { .title {
@apply mr-4 text-base tracking-tight md:text-2xl font-bold; @apply text-lg lg:text-2xl font-bold;
} }
.nav-main { .nav-main {
@apply fixed top-0 left-0 min-h-screen w-16 min-w-[4rem] overflow-hidden border-r border-stone-800 bg-coolgray-200 scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200 xl:overflow-visible; @apply fixed top-0 left-0 min-h-screen w-16 min-w-[4rem] overflow-hidden border-r border-stone-800 bg-coolgray-200 scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200 xl:overflow-visible;
@@ -197,6 +197,10 @@ a {
border: none; border: none;
} }
input {
@apply w-48 lg:w-96; .header {
} @apply flex flex-row z-10 w-full py-5 px-5;
}
.burger {
@apply block m-[2px] h-[3px] w-5 rounded
}