ui: change tooltips and info boxes
This commit is contained in:
parent
e1697848a5
commit
f6bb14f7c4
@ -14,15 +14,20 @@
|
||||
"format": "prettier --write --plugin-search-dir=. ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@floating-ui/dom": "1.0.1",
|
||||
"@playwright/test": "1.25.1",
|
||||
"@popperjs/core": "2.11.6",
|
||||
"@sveltejs/kit": "1.0.0-next.405",
|
||||
"@types/js-cookie": "3.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "5.35.1",
|
||||
"@typescript-eslint/parser": "5.35.1",
|
||||
"autoprefixer": "10.4.8",
|
||||
"classnames": "2.3.1",
|
||||
"eslint": "8.22.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"eslint-plugin-svelte3": "4.0.0",
|
||||
"flowbite": "1.5.2",
|
||||
"flowbite-svelte": "0.26.2",
|
||||
"postcss": "8.4.16",
|
||||
"prettier": "2.7.1",
|
||||
"prettier-plugin-svelte": "2.7.0",
|
||||
|
37
apps/ui/src/lib/components/DocLink.svelte
Normal file
37
apps/ui/src/lib/components/DocLink.svelte
Normal file
@ -0,0 +1,37 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import Tooltip from './Tooltip.svelte';
|
||||
export let isLink = false;
|
||||
export let explanation = '';
|
||||
let id: any;
|
||||
let self: any;
|
||||
onMount(() => {
|
||||
id = `info-${self.offsetLeft}-${self.offsetTop}`;
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<div {id} class="inline-block mx-2 text-pink-500 cursor-pointer" bind:this={self}>
|
||||
<svg
|
||||
fill="none"
|
||||
height="18"
|
||||
shape-rendering="geometricPrecision"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="1.5"
|
||||
viewBox="0 0 24 24"
|
||||
width="18"
|
||||
><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"
|
||||
/><circle cx="12" cy="17" r=".5" />
|
||||
</svg>
|
||||
</div>
|
||||
{#if id}
|
||||
{#if isLink}
|
||||
LINK
|
||||
{:else}
|
||||
<Tooltip triggeredBy={`#${id}`}>{@html explanation}</Tooltip>
|
||||
{/if}
|
||||
{/if}
|
@ -1,6 +1,8 @@
|
||||
<script lang="ts">
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import DocLink from './DocLink.svelte';
|
||||
import Tooltip from './Tooltip.svelte';
|
||||
|
||||
export let id: any;
|
||||
export let setting: any;
|
||||
export let title: any;
|
||||
export let description: any;
|
||||
@ -8,22 +10,17 @@
|
||||
export let disabled = false;
|
||||
export let dataTooltip: any = null;
|
||||
export let loading = false;
|
||||
let triggeredBy = `#${id}`;
|
||||
</script>
|
||||
|
||||
<div class="flex items-center py-4 pr-8 max-w-xs">
|
||||
<div class="flex items-center py-4 pr-8">
|
||||
<div class="flex w-96 flex-col">
|
||||
<div class="text-xs font-bold text-stone-100 md:text-base">{title}</div>
|
||||
<Explainer text={description} />
|
||||
<div class="text-xs font-bold text-stone-100 md:text-base">
|
||||
{title}<DocLink explanation={description} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class:tooltip-right={dataTooltip}
|
||||
class:tooltip-primary={dataTooltip}
|
||||
class:tooltip={dataTooltip}
|
||||
class:text-center={isCenter}
|
||||
data-tip={dataTooltip}
|
||||
class="flex justify-center"
|
||||
>
|
||||
<div class:text-center={isCenter} class="flex justify-center">
|
||||
<div
|
||||
on:click
|
||||
aria-pressed="false"
|
||||
@ -32,6 +29,7 @@
|
||||
class:bg-green-600={!loading && setting}
|
||||
class:bg-stone-700={!loading && !setting}
|
||||
class:bg-yellow-500={loading}
|
||||
{id}
|
||||
>
|
||||
<span class="sr-only">Use setting</span>
|
||||
<span
|
||||
@ -72,3 +70,7 @@
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if dataTooltip}
|
||||
<Tooltip {triggeredBy} placement="top">{dataTooltip}</Tooltip>
|
||||
{/if}
|
||||
|
8
apps/ui/src/lib/components/Tooltip.svelte
Normal file
8
apps/ui/src/lib/components/Tooltip.svelte
Normal file
@ -0,0 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { Tooltip } from 'flowbite-svelte';
|
||||
export let placement = 'bottom';
|
||||
export let color = 'bg-coollabs text-left';
|
||||
export let triggeredBy = '#tooltip-default';
|
||||
</script>
|
||||
|
||||
<Tooltip {triggeredBy} {placement} arrow={false} {color} style="custom"><slot /></Tooltip>
|
@ -209,7 +209,7 @@
|
||||
"expose_a_port": "Expose a port",
|
||||
"enable_preview_deploy_mr_pr_requests": "Enable preview deployments from pull or merge requests.",
|
||||
"debug_logs": "Debug Logs",
|
||||
"enable_debug_log_during_build": "Enable debug logs during build phase.<br><span class='text-red-500 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 font-bold'>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.",
|
||||
"no_applications_found": "No applications found",
|
||||
"secret__batch_dot_env": "Paste .env file",
|
||||
@ -275,7 +275,7 @@
|
||||
"application_id": "Application ID",
|
||||
"group_name": "Group Name",
|
||||
"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-orange-600' >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='font-bold text-settings' >in the URL</span> of your GitLab OAuth Application.",
|
||||
"register_oauth_gitlab": "Register new OAuth application on GitLab",
|
||||
"gitlab": {
|
||||
"self_hosted": "Instance-wide application (self-hosted)",
|
||||
|
@ -88,6 +88,7 @@
|
||||
import { errorNotification } from '$lib/common';
|
||||
import { appSession } from '$lib/store';
|
||||
import Toasts from '$lib/components/Toasts.svelte';
|
||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||
|
||||
if (userId) $appSession.userId = userId;
|
||||
if (teamId) $appSession.teamId = teamId;
|
||||
@ -132,12 +133,12 @@
|
||||
{/if}
|
||||
<div class="flex flex-col space-y-2 py-2" class:mt-2={$appSession.whiteLabeled}>
|
||||
<a
|
||||
id="dashboard"
|
||||
sveltekit:prefetch
|
||||
href="/"
|
||||
class="icons tooltip tooltip-primary tooltip-right bg-coolgray-200 hover:text-white"
|
||||
class="icons bg-coolgray-200 hover:text-white"
|
||||
class:text-white={$page.url.pathname === '/'}
|
||||
class:bg-coolgray-500={$page.url.pathname === '/'}
|
||||
data-tip="Dashboard"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -156,12 +157,13 @@
|
||||
<path d="M16 15c-2.21 1.333 -5.792 1.333 -8 0" />
|
||||
</svg>
|
||||
</a>
|
||||
<div class="border-t border-stone-700" />
|
||||
|
||||
<div class="border-t border-stone-700" />
|
||||
<a
|
||||
id="applications"
|
||||
sveltekit:prefetch
|
||||
href="/applications"
|
||||
class="icons tooltip tooltip-primary tooltip-right bg-coolgray-200"
|
||||
class="icons bg-coolgray-200"
|
||||
class:text-applications={$page.url.pathname.startsWith('/applications') ||
|
||||
$page.url.pathname.startsWith('/new/application')}
|
||||
class:bg-coolgray-500={$page.url.pathname.startsWith('/applications') ||
|
||||
@ -186,10 +188,12 @@
|
||||
<line x1="17" y1="4" x2="17" y2="10" />
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<a
|
||||
id="sources"
|
||||
sveltekit:prefetch
|
||||
href="/sources"
|
||||
class="icons tooltip tooltip-primary tooltip-right bg-coolgray-200"
|
||||
class="icons bg-coolgray-200"
|
||||
class:text-sources={$page.url.pathname.startsWith('/sources') ||
|
||||
$page.url.pathname.startsWith('/new/source')}
|
||||
class:bg-coolgray-500={$page.url.pathname.startsWith('/sources') ||
|
||||
@ -216,9 +220,10 @@
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
id="destinations"
|
||||
sveltekit:prefetch
|
||||
href="/destinations"
|
||||
class="icons tooltip tooltip-primary tooltip-right bg-coolgray-200"
|
||||
class="icons bg-coolgray-200"
|
||||
class:text-destinations={$page.url.pathname.startsWith('/destinations') ||
|
||||
$page.url.pathname.startsWith('/new/destination')}
|
||||
class:bg-coolgray-500={$page.url.pathname.startsWith('/destinations') ||
|
||||
@ -251,9 +256,10 @@
|
||||
</a>
|
||||
<div class="border-t border-stone-700" />
|
||||
<a
|
||||
id="databases"
|
||||
sveltekit:prefetch
|
||||
href="/databases"
|
||||
class="icons tooltip tooltip-primary tooltip-right bg-coolgray-200"
|
||||
class="icons bg-coolgray-200"
|
||||
class:text-databases={$page.url.pathname.startsWith('/databases') ||
|
||||
$page.url.pathname.startsWith('/new/database')}
|
||||
class:bg-coolgray-500={$page.url.pathname.startsWith('/databases') ||
|
||||
@ -277,9 +283,10 @@
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
id="services"
|
||||
sveltekit:prefetch
|
||||
href="/services"
|
||||
class="icons tooltip tooltip-primary tooltip-right bg-coolgray-200"
|
||||
class="icons bg-coolgray-200"
|
||||
class:text-services={$page.url.pathname.startsWith('/services') ||
|
||||
$page.url.pathname.startsWith('/new/service')}
|
||||
class:bg-coolgray-500={$page.url.pathname.startsWith('/services') ||
|
||||
@ -306,9 +313,10 @@
|
||||
<UpdateAvailable />
|
||||
<div class="flex flex-col space-y-2 py-2">
|
||||
<a
|
||||
id="iam"
|
||||
sveltekit:prefetch
|
||||
href="/iam"
|
||||
class="icons tooltip tooltip-primary tooltip-right bg-coolgray-200"
|
||||
class="icons bg-coolgray-200"
|
||||
class:text-iam={$page.url.pathname.startsWith('/iam')}
|
||||
class:bg-coolgray-500={$page.url.pathname.startsWith('/iam')}
|
||||
data-tip="IAM"
|
||||
@ -330,9 +338,10 @@
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
id="settings"
|
||||
sveltekit:prefetch
|
||||
href={$appSession.teamId === '0' ? '/settings/global' : '/settings/ssh-keys'}
|
||||
class="icons tooltip tooltip-primary tooltip-right bg-coolgray-200"
|
||||
class="icons bg-coolgray-200"
|
||||
class:text-settings={$page.url.pathname.startsWith('/settings')}
|
||||
class:bg-coolgray-500={$page.url.pathname.startsWith('/settings')}
|
||||
data-tip="Settings"
|
||||
@ -356,7 +365,8 @@
|
||||
</a>
|
||||
|
||||
<div
|
||||
class="icons tooltip tooltip-primary tooltip-right bg-coolgray-200 hover:text-error"
|
||||
id="logout"
|
||||
class="icons bg-coolgray-200 hover:text-error"
|
||||
data-tip="Logout"
|
||||
on:click={logout}
|
||||
>
|
||||
@ -400,3 +410,16 @@
|
||||
<slot />
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<Tooltip triggeredBy="#dashboard" placement="right">Dashboard</Tooltip>
|
||||
<Tooltip triggeredBy="#applications" placement="right" color="bg-applications">Applications</Tooltip
|
||||
>
|
||||
<Tooltip triggeredBy="#sources" placement="right" color="bg-sources">Git Sources</Tooltip>
|
||||
<Tooltip triggeredBy="#destinations" placement="right" color="bg-destinations">Destinations</Tooltip
|
||||
>
|
||||
<Tooltip triggeredBy="#databases" placement="right" color="bg-databases">Databases</Tooltip>
|
||||
<Tooltip triggeredBy="#services" placement="right" color="bg-services">Services</Tooltip>
|
||||
<Tooltip triggeredBy="#iam" placement="right" color="bg-iam">IAM</Tooltip>
|
||||
<Tooltip triggeredBy="#settings" placement="right" color="bg-settings text-black">Settings</Tooltip
|
||||
>
|
||||
<Tooltip triggeredBy="#logout" placement="right" color="bg-red-600">Logout</Tooltip>
|
||||
|
@ -62,6 +62,7 @@
|
||||
import { t } from '$lib/translations';
|
||||
import { appSession, disabledButton, status, location, setLocation, addToast } from '$lib/store';
|
||||
import { errorNotification, handlerNotFoundLoad } from '$lib/common';
|
||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||
|
||||
let statusInterval: any;
|
||||
$disabledButton =
|
||||
@ -115,6 +116,10 @@
|
||||
$status.application.initialLoading = true;
|
||||
$status.application.loading = true;
|
||||
await post(`/applications/${id}/restart`, {});
|
||||
addToast({
|
||||
type: 'success',
|
||||
message: 'Restart successful.'
|
||||
});
|
||||
} catch (error) {
|
||||
return errorNotification(error);
|
||||
} finally {
|
||||
@ -174,9 +179,10 @@
|
||||
<nav class="nav-side">
|
||||
{#if $location}
|
||||
<a
|
||||
id="open"
|
||||
href={$location}
|
||||
target="_blank"
|
||||
class="icons tooltip-bottom flex items-center bg-transparent text-sm"
|
||||
class="icons flex items-center bg-transparent text-sm"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6"
|
||||
@ -193,14 +199,16 @@
|
||||
<polyline points="15 4 20 4 20 9" />
|
||||
</svg></a
|
||||
>
|
||||
<Tooltip triggeredBy="#open">Open</Tooltip>
|
||||
|
||||
<div class="border border-coolgray-500 h-8" />
|
||||
{/if}
|
||||
|
||||
{#if $status.application.isExited}
|
||||
<a
|
||||
id="applicationerror"
|
||||
href={!$disabledButton ? `/applications/${id}/logs` : null}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm flex items-center text-error"
|
||||
data-tip="Application exited with an error!"
|
||||
class="icons bg-transparent text-sm flex items-center text-error"
|
||||
sveltekit:prefetch
|
||||
>
|
||||
<svg
|
||||
@ -221,10 +229,11 @@
|
||||
<line x1="12" y1="16" x2="12.01" y2="16" />
|
||||
</svg>
|
||||
</a>
|
||||
<Tooltip triggeredBy="#applicationerror">Application exited with an error!</Tooltip>
|
||||
{/if}
|
||||
{#if $status.application.initialLoading}
|
||||
<button
|
||||
class="icons tooltip-bottom flex animate-spin items-center space-x-2 bg-transparent text-sm duration-500 ease-in-out"
|
||||
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"
|
||||
@ -247,13 +256,11 @@
|
||||
</button>
|
||||
{:else if $status.application.isRunning}
|
||||
<button
|
||||
id="stop"
|
||||
on:click={stopApplication}
|
||||
type="submit"
|
||||
disabled={$disabledButton}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm flex items-center space-x-2 text-error"
|
||||
data-tip={$appSession.isAdmin
|
||||
? 'Stop'
|
||||
: $t('application.permission_denied_stop_application')}
|
||||
class="icons bg-transparent text-sm flex items-center space-x-2 text-error"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -270,14 +277,14 @@
|
||||
<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={$disabledButton}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm flex items-center space-x-2 "
|
||||
data-tip={$appSession.isAdmin
|
||||
? 'Restart (useful for changing secrets)'
|
||||
: $t('application.permission_denied_stop_application')}
|
||||
class="icons bg-transparent text-sm flex items-center space-x-2"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -294,14 +301,14 @@
|
||||
<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={$disabledButton}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm flex items-center space-x-2"
|
||||
data-tip={$appSession.isAdmin
|
||||
? 'Force Rebuild without cache'
|
||||
: 'You do not have permission to rebuild application.'}
|
||||
class="icons bg-transparent text-sm flex items-center space-x-2"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -320,16 +327,15 @@
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<Tooltip triggeredBy="#forceredeploy">Force redeploy (without cache)</Tooltip>
|
||||
</form>
|
||||
{:else}
|
||||
<form on:submit|preventDefault={() => handleDeploySubmit(false)}>
|
||||
<button
|
||||
id="deploy"
|
||||
type="submit"
|
||||
disabled={$disabledButton}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm flex items-center space-x-2 text-success"
|
||||
data-tip={$appSession.isAdmin
|
||||
? 'Deploy'
|
||||
: 'You do not have permission to deploy application.'}
|
||||
class="icons bg-transparent text-sm flex items-center space-x-2 text-success"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -345,22 +351,20 @@
|
||||
<path d="M7 4v16l13 -8z" />
|
||||
</svg>
|
||||
</button>
|
||||
<Tooltip triggeredBy="#deploy">Deploy</Tooltip>
|
||||
</form>
|
||||
{/if}
|
||||
|
||||
<div class="border border-coolgray-500 h-8" />
|
||||
<a
|
||||
id="configurations"
|
||||
href={!$disabledButton ? `/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={$disabledButton}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm"
|
||||
data-tip="Configurations"
|
||||
>
|
||||
<button disabled={$disabledButton} class="icons bg-transparent text-sm">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6"
|
||||
@ -385,17 +389,14 @@
|
||||
></a
|
||||
>
|
||||
<a
|
||||
id="secrets"
|
||||
href={!$disabledButton ? `/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
|
||||
disabled={$disabledButton}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm"
|
||||
data-tip="Secrets"
|
||||
>
|
||||
<button disabled={$disabledButton} class="icons bg-transparent text-sm">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-6 h-6"
|
||||
@ -416,17 +417,14 @@
|
||||
></a
|
||||
>
|
||||
<a
|
||||
id="persistentstorages"
|
||||
href={!$disabledButton ? `/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
|
||||
disabled={$disabledButton}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm"
|
||||
data-tip="Persistent Storages"
|
||||
>
|
||||
<button disabled={$disabledButton} class="icons bg-transparent text-sm">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-6 h-6"
|
||||
@ -446,17 +444,14 @@
|
||||
>
|
||||
{#if !application.settings.isBot}
|
||||
<a
|
||||
id="previews"
|
||||
href={!$disabledButton ? `/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
|
||||
disabled={$disabledButton}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm"
|
||||
data-tip="Previews"
|
||||
>
|
||||
<button disabled={$disabledButton} class="icons bg-transparent text-sm">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-6 h-6"
|
||||
@ -479,6 +474,7 @@
|
||||
{/if}
|
||||
<div class="border border-coolgray-500 h-8" />
|
||||
<a
|
||||
id="applicationlogs"
|
||||
href={!$disabledButton && $status.application.isRunning ? `/applications/${id}/logs` : null}
|
||||
sveltekit:prefetch
|
||||
class="hover:text-sky-500 rounded"
|
||||
@ -487,8 +483,7 @@
|
||||
>
|
||||
<button
|
||||
disabled={$disabledButton || !$status.application.isRunning}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm"
|
||||
data-tip={$t('application.logs')}
|
||||
class="icons bg-transparent text-sm"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -510,17 +505,14 @@
|
||||
</button></a
|
||||
>
|
||||
<a
|
||||
id="buildlogs"
|
||||
href={!$disabledButton ? `/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
|
||||
disabled={$disabledButton}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm"
|
||||
data-tip="Build Logs"
|
||||
>
|
||||
<button disabled={$disabledButton} class="icons bg-transparent text-sm">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6"
|
||||
@ -546,16 +538,22 @@
|
||||
<div class="border border-coolgray-500 h-8" />
|
||||
|
||||
<button
|
||||
id="delete"
|
||||
on:click={() => deleteApplication(application.name)}
|
||||
type="submit"
|
||||
disabled={!$appSession.isAdmin}
|
||||
class:hover:text-red-500={$appSession.isAdmin}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm"
|
||||
data-tip={$appSession.isAdmin
|
||||
? $t('application.delete_application')
|
||||
: $t('application.permission_denied_delete_application')}
|
||||
class="icons bg-transparent text-sm"
|
||||
>
|
||||
<DeleteIcon />
|
||||
</button>
|
||||
</nav>
|
||||
<slot />
|
||||
|
||||
<Tooltip triggeredBy="#configurations">Configurations</Tooltip>
|
||||
<Tooltip triggeredBy="#secrets">Secrets</Tooltip>
|
||||
<Tooltip triggeredBy="#persistentstorages">Persistent Storages</Tooltip>
|
||||
<Tooltip triggeredBy="#previews">Previews</Tooltip>
|
||||
<Tooltip triggeredBy="#applicationlogs">Application Logs</Tooltip>
|
||||
<Tooltip triggeredBy="#buildlogs">Build Logs</Tooltip>
|
||||
<Tooltip triggeredBy="#delete">Delete</Tooltip>
|
||||
|
@ -164,7 +164,6 @@
|
||||
<div class="space-y-4">
|
||||
<input
|
||||
placeholder="eg: https://github.com/coollabsio/nodejs-example/tree/main"
|
||||
class="text-xs"
|
||||
bind:value={publicRepositoryLink}
|
||||
/>
|
||||
{#if branchSelectOptions.length > 0}
|
||||
@ -193,7 +192,5 @@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<Explainer
|
||||
text="Examples:<br><br>https://github.com/coollabsio/nodejs-example<br>https://github.com/coollabsio/nodejs-example/tree/main<br>https://gitlab.com/aleveha/fastify-example<br>https://gitlab.com/aleveha/fastify-example/-/tree/master<br><br>Only works with Github.com and Gitlab.com."
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
@ -32,7 +32,8 @@
|
||||
import { errorNotification } from '$lib/common';
|
||||
import { appSession } from '$lib/store';
|
||||
import PublicRepository from './_PublicRepository.svelte';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
|
||||
const { id } = $page.params;
|
||||
const from = $page.url.searchParams.get('from');
|
||||
@ -192,7 +193,6 @@ import Explainer from '$lib/components/Explainer.svelte';
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="title py-4">Public Repository</div>
|
||||
|
||||
<PublicRepository />
|
||||
<div class="title py-4">Public Repository <DocLink /></div>
|
||||
<PublicRepository />
|
||||
</div>
|
||||
|
@ -39,7 +39,9 @@
|
||||
import { addToast, appSession, disabledButton, setLocation, status } from '$lib/store';
|
||||
import { t } from '$lib/translations';
|
||||
import { errorNotification, getDomain, notNodeDeployments, staticDeployments } from '$lib/common';
|
||||
import Setting from './_Setting.svelte';
|
||||
import Setting from '$lib/components/Setting.svelte';
|
||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
const { id } = $page.params;
|
||||
|
||||
$: isDisabled =
|
||||
@ -281,6 +283,7 @@
|
||||
</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"
|
||||
@ -321,6 +324,7 @@
|
||||
</svg>
|
||||
{/if}
|
||||
</a>
|
||||
<Tooltip triggeredBy="#git">Open on Git</Tooltip>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@ -426,7 +430,7 @@
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center pb-8">
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="destination" class="text-base font-bold text-stone-100"
|
||||
>{$t('application.destination')}</label
|
||||
>
|
||||
@ -440,10 +444,15 @@
|
||||
</div>
|
||||
</div>
|
||||
{#if application.buildCommand || application.buildPack === 'rust' || application.buildPack === 'laravel'}
|
||||
<div class="grid grid-cols-2 items-center pb-8">
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="baseBuildImage" class="text-base font-bold text-stone-100"
|
||||
>{$t('application.base_build_image')}</label
|
||||
>
|
||||
>{$t('application.base_build_image')}
|
||||
<DocLink
|
||||
explanation={application.buildPack === 'laravel'
|
||||
? 'For building frontend assets with webpack.'
|
||||
: 'Image that will be used during the build process.'}
|
||||
/>
|
||||
</label>
|
||||
|
||||
<div class="custom-select-wrapper">
|
||||
<Select
|
||||
@ -457,17 +466,13 @@
|
||||
isClearable={false}
|
||||
/>
|
||||
</div>
|
||||
{#if application.buildPack === 'laravel'}
|
||||
<Explainer text="For building frontend assets with webpack." />
|
||||
{:else}
|
||||
<Explainer text={$t('application.base_build_image_explainer')} />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{#if application.buildPack !== 'docker'}
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="baseImage" class="text-base font-bold text-stone-100"
|
||||
>{$t('application.base_image')}</label
|
||||
>{$t('application.base_image')}
|
||||
<DocLink explanation={'Image that will be used for the deployment.'} /></label
|
||||
>
|
||||
<div class="custom-select-wrapper">
|
||||
<Select
|
||||
@ -481,13 +486,15 @@
|
||||
isClearable={false}
|
||||
/>
|
||||
</div>
|
||||
<Explainer text={$t('application.base_image_explainer')} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if application.buildPack !== 'docker' && (application.buildPack === 'nextjs' || application.buildPack === 'nuxtjs')}
|
||||
<div class="grid grid-cols-2 items-center pb-8">
|
||||
<label for="deploymentType" class="text-base font-bold text-stone-100"
|
||||
>Deployment Type</label
|
||||
>Deployment Type
|
||||
<DocLink
|
||||
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."}
|
||||
/></label
|
||||
>
|
||||
<div class="custom-select-wrapper">
|
||||
<Select
|
||||
@ -501,9 +508,6 @@
|
||||
isClearable={false}
|
||||
/>
|
||||
</div>
|
||||
<Explainer
|
||||
text="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."
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
@ -513,26 +517,36 @@
|
||||
<div class="grid grid-flow-row gap-2 px-10">
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<Setting
|
||||
id="isBot"
|
||||
isCenter={false}
|
||||
bind:setting={isBot}
|
||||
on:click={() => changeSettings('isBot')}
|
||||
title="Is your application a bot?"
|
||||
description="You can deploy applications without domains. <br>You can also make them to listen on <span class='text-green-500 font-bold'>IP:EXPOSEDPORT</span> as well.<br></Setting><br>Useful to host <span class='text-green-500 font-bold'>Twitch bots, regular jobs, or anything that does not require an incoming connection.</span>"
|
||||
description="You can deploy applications without domains or make them to listen on the <span class='text-settings font-bold'>Exposed Port</span>.<br></Setting><br>Useful to host <span class='text-settings font-bold'>Twitch bots, regular jobs, or anything that does not require an incoming HTTP connection.</span>"
|
||||
disabled={$status.application.isRunning}
|
||||
/>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center pb-8">
|
||||
<Setting
|
||||
id="dualCerts"
|
||||
dataTooltip={$t('forms.must_be_stopped_to_modify')}
|
||||
disabled={$status.application.isRunning}
|
||||
isCenter={false}
|
||||
bind:setting={dualCerts}
|
||||
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."
|
||||
on:click={() => !$status.application.isRunning && changeSettings('dualCerts')}
|
||||
/>
|
||||
</div>
|
||||
{#if !isBot}
|
||||
<div class="grid grid-cols-2">
|
||||
<div class="flex-col">
|
||||
<label for="fqdn" class="pt-2 text-base font-bold text-stone-100"
|
||||
>{$t('application.url_fqdn')}</label
|
||||
>
|
||||
{#if browser && window.location.hostname === 'demo.coolify.io'}
|
||||
<Explainer
|
||||
text="<span class='text-white font-bold'>You can use the predefined random url name or enter your own domain name.</span>"
|
||||
>{$t('application.url_fqdn')}
|
||||
<DocLink
|
||||
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>"}
|
||||
/>
|
||||
{/if}
|
||||
<Explainer text={$t('application.https_explainer')} />
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<input
|
||||
@ -582,17 +596,6 @@
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center pb-8">
|
||||
<Setting
|
||||
dataTooltip={$t('forms.must_be_stopped_to_modify')}
|
||||
disabled={$status.application.isRunning}
|
||||
isCenter={false}
|
||||
bind:setting={dualCerts}
|
||||
title={$t('application.ssl_www_and_non_www')}
|
||||
description={$t('application.ssl_explainer')}
|
||||
on:click={() => !$status.application.isRunning && changeSettings('dualCerts')}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{#if application.buildPack === 'python'}
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
@ -658,7 +661,11 @@
|
||||
</div>
|
||||
{/if}
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="exposePort" class="text-base font-bold text-stone-100">Exposed Port</label>
|
||||
<label for="exposePort" class="text-base font-bold text-stone-100"
|
||||
>Exposed Port <DocLink
|
||||
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
|
||||
>
|
||||
<input
|
||||
readonly={!$appSession.isAdmin && !$status.application.isRunning}
|
||||
disabled={isDisabled}
|
||||
@ -667,9 +674,6 @@
|
||||
bind:value={application.exposePort}
|
||||
placeholder="12345"
|
||||
/>
|
||||
<Explainer
|
||||
text={'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.'}
|
||||
/>
|
||||
</div>
|
||||
{#if !notNodeDeployments.includes(application.buildPack)}
|
||||
<div class="grid grid-cols-2 items-center pt-4">
|
||||
@ -715,7 +719,9 @@
|
||||
{#if application.buildPack === 'docker'}
|
||||
<div class="grid grid-cols-2 items-center pt-4">
|
||||
<label for="dockerFileLocation" class="text-base font-bold text-stone-100"
|
||||
>Dockerfile Location</label
|
||||
>Dockerfile Location <DocLink
|
||||
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
|
||||
>
|
||||
<input
|
||||
disabled={isDisabled}
|
||||
@ -725,9 +731,6 @@
|
||||
bind:value={application.dockerFileLocation}
|
||||
placeholder="default: /Dockerfile"
|
||||
/>
|
||||
<Explainer
|
||||
text="Should be absolute path, like <span class='text-green-500 font-bold'>/data/Dockerfile</span> or <span class='text-green-500 font-bold'>/Dockerfile.</span>"
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{#if application.buildPack === 'deno'}
|
||||
@ -743,7 +746,11 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="denoOptions" class="text-base font-bold text-stone-100">Arguments</label>
|
||||
<label for="denoOptions" class="text-base font-bold text-stone-100"
|
||||
>Arguments <DocLink
|
||||
explanation={"List of arguments to pass to <span class='text-settings font-bold'>deno run</span> command. Could include permissions, configurations files, etc."}
|
||||
/></label
|
||||
>
|
||||
<input
|
||||
disabled={isDisabled}
|
||||
readonly={!$appSession.isAdmin}
|
||||
@ -752,18 +759,17 @@
|
||||
bind:value={application.denoOptions}
|
||||
placeholder="eg: --allow-net --allow-hrtime --config path/to/file.json"
|
||||
/>
|
||||
<Explainer
|
||||
text="List of arguments to pass to <span class='text-green-500 font-bold'>deno run</span> command. Could include permissions, configurations files, etc."
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{#if application.buildPack !== 'laravel' && application.buildPack !== 'heroku'}
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<div class="flex-col">
|
||||
<label for="baseDirectory" class="pt-2 text-base font-bold text-stone-100"
|
||||
>{$t('forms.base_directory')}</label
|
||||
>{$t('forms.base_directory')}
|
||||
<DocLink
|
||||
explanation={"Directory to use as the base for all commands.<br>Could be useful with <span class='text-settings font-bold'>monorepos</span>."}
|
||||
/></label
|
||||
>
|
||||
<Explainer text={$t('application.directory_to_use_explainer')} />
|
||||
</div>
|
||||
<input
|
||||
disabled={isDisabled}
|
||||
@ -779,9 +785,11 @@
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<div class="flex-col">
|
||||
<label for="publishDirectory" class="pt-2 text-base font-bold text-stone-100"
|
||||
>{$t('forms.publish_directory')}</label
|
||||
>{$t('forms.publish_directory')}
|
||||
<DocLink
|
||||
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>."}
|
||||
/></label
|
||||
>
|
||||
<Explainer text={$t('application.publish_directory_explainer')} />
|
||||
</div>
|
||||
|
||||
<input
|
||||
@ -804,6 +812,7 @@
|
||||
{#if !application.settings.isPublicRepository}
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<Setting
|
||||
id="autodeploy"
|
||||
isCenter={false}
|
||||
bind:setting={autodeploy}
|
||||
on:click={() => changeSettings('autodeploy')}
|
||||
@ -815,6 +824,7 @@
|
||||
{#if !application.settings.isBot}
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<Setting
|
||||
id="previews"
|
||||
isCenter={false}
|
||||
bind:setting={previews}
|
||||
on:click={() => changeSettings('previews')}
|
||||
@ -825,6 +835,7 @@
|
||||
{/if}
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<Setting
|
||||
id="debug"
|
||||
isCenter={false}
|
||||
bind:setting={debug}
|
||||
on:click={() => changeSettings('debug')}
|
||||
|
@ -11,6 +11,7 @@
|
||||
import { t } from '$lib/translations';
|
||||
import LoadingLogs from '$lib/components/LoadingLogs.svelte';
|
||||
import { errorNotification } from '$lib/common';
|
||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||
|
||||
let logs: any = [];
|
||||
let loading = true;
|
||||
@ -108,9 +109,9 @@
|
||||
{:else}
|
||||
<div class="flex justify-end sticky top-0 p-2 mx-1">
|
||||
<button
|
||||
id="follow"
|
||||
on:click={followBuild}
|
||||
class="bg-transparent btn btn-sm btn-link tooltip tooltip-primary tooltip-bottom hover:text-green-500 hover:bg-coolgray-500"
|
||||
data-tip="Follow logs"
|
||||
class="bg-transparent btn btn-sm btn-linkhover:text-green-500 hover:bg-coolgray-500"
|
||||
class:text-green-500={followingBuild}
|
||||
>
|
||||
<svg
|
||||
@ -130,12 +131,13 @@
|
||||
<line x1="16" y1="12" x2="12" y2="16" />
|
||||
</svg>
|
||||
</button>
|
||||
<Tooltip triggeredBy="#follow">Follow Logs</Tooltip>
|
||||
{#if currentStatus === 'running'}
|
||||
<button
|
||||
id="cancel"
|
||||
on:click={cancelBuild}
|
||||
class:animation-spin={cancelInprogress}
|
||||
class="bg-transparent btn btn-sm btn-link hover:text-red-500 hover:bg-coolgray-500 tooltip tooltip-primary tooltip-bottom"
|
||||
data-tip="Cancel build"
|
||||
class="bg-transparent btn btn-sm btn-link hover:text-red-500 hover:bg-coolgray-500"
|
||||
>
|
||||
{#if cancelInprogress}
|
||||
Cancelling...
|
||||
@ -156,6 +158,7 @@
|
||||
</svg>
|
||||
{/if}
|
||||
</button>
|
||||
<Tooltip triggeredBy="#cancel">Cancel build</Tooltip>
|
||||
{/if}
|
||||
</div>
|
||||
{#if logs.length > 0}
|
||||
|
@ -5,6 +5,7 @@
|
||||
import { errorNotification } from '$lib/common';
|
||||
import LoadingLogs from '$lib/components/LoadingLogs.svelte';
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||
|
||||
let application: any = {};
|
||||
let logsLoading = false;
|
||||
@ -146,9 +147,9 @@
|
||||
{/if}
|
||||
<div class="flex justify-end sticky top-0 p-1 mx-1">
|
||||
<button
|
||||
id="follow"
|
||||
on:click={followBuild}
|
||||
class="bg-transparent btn btn-sm btn-link tooltip tooltip-primary tooltip-bottom"
|
||||
data-tip="Follow logs"
|
||||
class="bg-transparent btn btn-sm btn-link"
|
||||
class:text-green-500={followingLogs}
|
||||
>
|
||||
<svg
|
||||
@ -168,6 +169,7 @@
|
||||
<line x1="16" y1="12" x2="12" y2="16" />
|
||||
</svg>
|
||||
</button>
|
||||
<Tooltip triggeredBy="#follow">Follow Logs</Tooltip>
|
||||
</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"
|
||||
|
@ -61,6 +61,7 @@
|
||||
import { appSession, status, disabledButton } from '$lib/store';
|
||||
import DeleteIcon from '$lib/components/DeleteIcon.svelte';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||
const { id } = $page.params;
|
||||
|
||||
let statusInterval: any = false;
|
||||
@ -143,9 +144,9 @@
|
||||
{#if database.type && database.destinationDockerId && database.version && database.defaultDatabase}
|
||||
{#if $status.database.isExited}
|
||||
<a
|
||||
id="exited"
|
||||
href={!$disabledButton ? `/databases/${id}/logs` : null}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm flex items-center text-red-500 tooltip-error"
|
||||
data-tip="Service exited with an error!"
|
||||
class="icons bg-transparent text-sm flex items-center text-red-500 tooltip-error"
|
||||
sveltekit:prefetch
|
||||
>
|
||||
<svg
|
||||
@ -166,10 +167,11 @@
|
||||
<line x1="12" y1="16" x2="12.01" y2="16" />
|
||||
</svg>
|
||||
</a>
|
||||
<Tooltip triggeredBy="#exited">{'Service exited with an error!'}</Tooltip>
|
||||
{/if}
|
||||
{#if $status.database.initialLoading}
|
||||
<button
|
||||
class="icons tooltip-bottom flex animate-spin items-center space-x-2 bg-transparent text-sm duration-500 ease-in-out"
|
||||
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"
|
||||
@ -192,13 +194,11 @@
|
||||
</button>
|
||||
{:else if $status.database.isRunning}
|
||||
<button
|
||||
id="stop"
|
||||
on:click={stopDatabase}
|
||||
type="submit"
|
||||
disabled={!$appSession.isAdmin}
|
||||
class="icons bg-transparent tooltip tooltip-bottom text-sm flex items-center space-x-2 text-red-500"
|
||||
data-tip={$appSession.isAdmin
|
||||
? $t('database.stop_database')
|
||||
: $t('database.permission_denied_stop_database')}
|
||||
class="icons bg-transparent text-sm flex items-center space-x-2 text-red-500"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -215,15 +215,14 @@
|
||||
<rect x="14" y="5" width="4" height="14" rx="1" />
|
||||
</svg>
|
||||
</button>
|
||||
<Tooltip triggeredBy="#stop">{'Stop'}</Tooltip>
|
||||
{:else}
|
||||
<button
|
||||
id="start"
|
||||
on:click={startDatabase}
|
||||
type="submit"
|
||||
disabled={!$appSession.isAdmin}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm flex items-center space-x-2 text-green-500"
|
||||
data-tip={$appSession.isAdmin
|
||||
? $t('database.start_database')
|
||||
: $t('database.permission_denied_start_database')}
|
||||
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"
|
||||
@ -238,20 +237,19 @@
|
||||
<path d="M7 4v16l13 -8z" />
|
||||
</svg>
|
||||
</button>
|
||||
<Tooltip triggeredBy="#start">{'Start'}</Tooltip>
|
||||
{/if}
|
||||
{/if}
|
||||
<div class="border border-stone-700 h-8" />
|
||||
<a
|
||||
id="configuration"
|
||||
href="/databases/{id}"
|
||||
sveltekit:prefetch
|
||||
class="hover:text-yellow-500 rounded"
|
||||
class:text-yellow-500={$page.url.pathname === `/databases/${id}`}
|
||||
class:bg-coolgray-500={$page.url.pathname === `/databases/${id}`}
|
||||
>
|
||||
<button
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm disabled:text-red-500"
|
||||
data-tip={$t('application.configurations')}
|
||||
>
|
||||
<button class="icons bg-transparent m text-sm disabled:text-red-500">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6"
|
||||
@ -275,19 +273,17 @@
|
||||
</svg></button
|
||||
></a
|
||||
>
|
||||
<Tooltip triggeredBy="#configuration">{'Configuration'}</Tooltip>
|
||||
<div class="border border-stone-700 h-8" />
|
||||
<a
|
||||
id="databaselogs"
|
||||
href={$status.database.isRunning ? `/databases/${id}/logs` : null}
|
||||
sveltekit:prefetch
|
||||
class="hover:text-pink-500 rounded"
|
||||
class:text-pink-500={$page.url.pathname === `/databases/${id}/logs`}
|
||||
class:bg-coolgray-500={$page.url.pathname === `/databases/${id}/logs`}
|
||||
>
|
||||
<button
|
||||
disabled={!$status.database.isRunning}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm"
|
||||
data-tip={$t('database.logs')}
|
||||
>
|
||||
<button disabled={!$status.database.isRunning} class="icons bg-transparent text-sm">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6"
|
||||
@ -307,16 +303,16 @@
|
||||
</svg></button
|
||||
></a
|
||||
>
|
||||
<Tooltip triggeredBy="#databaselogs">{'Logs'}</Tooltip>
|
||||
<button
|
||||
id="delete"
|
||||
on:click={deleteDatabase}
|
||||
type="submit"
|
||||
disabled={!$appSession.isAdmin}
|
||||
class:hover:text-red-500={$appSession.isAdmin}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm"
|
||||
data-tip={$appSession.isAdmin
|
||||
? $t('database.delete_database')
|
||||
: $t('database.permission_denied_delete_database')}><DeleteIcon /></button
|
||||
class="icons bg-transparent text-sm"><DeleteIcon /></button
|
||||
>
|
||||
<Tooltip triggeredBy="#delete">{'Delete'}</Tooltip>
|
||||
</nav>
|
||||
{/if}
|
||||
<slot />
|
||||
|
@ -6,6 +6,7 @@
|
||||
import { get } from '$lib/api';
|
||||
import { t } from '$lib/translations';
|
||||
import { errorNotification } from '$lib/common';
|
||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||
|
||||
const { id } = $page.params;
|
||||
|
||||
@ -129,9 +130,9 @@
|
||||
{/if}
|
||||
<div class="flex justify-end sticky top-0 p-1 mx-1">
|
||||
<button
|
||||
id="follow"
|
||||
on:click={followBuild}
|
||||
class="bg-transparent btn btn-sm tooltip tooltip-primary tooltip-bottom"
|
||||
data-tip="Follow logs"
|
||||
class="bg-transparent btn btn-sm"
|
||||
class:text-green-500={followingLogs}
|
||||
>
|
||||
<svg
|
||||
@ -151,6 +152,7 @@
|
||||
<line x1="16" y1="12" x2="12" y2="16" />
|
||||
</svg>
|
||||
</button>
|
||||
<Tooltip triggeredBy="#follow">Follow Logs</Tooltip>
|
||||
</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"
|
||||
|
@ -196,14 +196,15 @@
|
||||
/>
|
||||
</div>
|
||||
{#if $appSession.teamId === '0'}
|
||||
<div class="grid lg:grid-cols-2 items-center">
|
||||
<div class="grid lg:grid-cols-2 items-center px-10">
|
||||
<Setting
|
||||
id="changeProxySetting"
|
||||
loading={loading.proxy}
|
||||
disabled={cannotDisable}
|
||||
bind:setting={destination.isCoolifyProxyUsed}
|
||||
on:click={changeProxySetting}
|
||||
title={$t('destination.use_coolify_proxy')}
|
||||
description={`This will install a proxy on the destination to allow you to access your applications and services without any manual configuration. Databases will have their own proxy. <br><br>${
|
||||
description={`This will install a proxy on the destination to allow you to access your applications and services without any manual configuration.${
|
||||
cannotDisable
|
||||
? '<span class="font-bold text-white">You cannot disable this proxy as FQDN is configured for Coolify.</span>'
|
||||
: ''
|
||||
|
@ -33,11 +33,7 @@
|
||||
<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="title font-bold">{$t('forms.configuration')}</div>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-sm bg-destinations"
|
||||
class:loading={loading}
|
||||
disabled={loading}
|
||||
<button type="submit" class="btn btn-sm bg-destinations" class:loading disabled={loading}
|
||||
>{loading
|
||||
? payload.isCoolifyProxyUsed
|
||||
? $t('destination.new.saving_and_configuring_proxy')
|
||||
@ -69,12 +65,13 @@
|
||||
/>
|
||||
</div>
|
||||
{#if $appSession.teamId === '0'}
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<div class="grid grid-cols-2 items-center px-10">
|
||||
<Setting
|
||||
id="changeProxySetting"
|
||||
bind:setting={payload.isCoolifyProxyUsed}
|
||||
on:click={() => (payload.isCoolifyProxyUsed = !payload.isCoolifyProxyUsed)}
|
||||
title={$t('destination.use_coolify_proxy')}
|
||||
description={$t('destination.new.install_proxy')}
|
||||
description={'This will install a proxy on the destination to allow you to access your applications and services without any manual configuration.'}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -33,18 +33,14 @@
|
||||
customClass="max-w-[32rem]"
|
||||
text="Remote Docker Engines are using <span class='text-white font-bold'>SSH</span> to communicate with the remote docker engine.
|
||||
You need to setup an <span class='text-white font-bold'>SSH key</span> in advance on the server and install Docker.
|
||||
<br>See <a class='text-white' href='https://docs.coollabs.io/coolify/destinations#remote-docker-engine'>docs</a> for more details."
|
||||
<br>See <a class='text-white' href='https://docs.coollabs.io/coolify/destinations#remote-docker-engine' target='blank'>docs</a> for more details."
|
||||
/>
|
||||
</div>
|
||||
<div class="flex justify-center px-6 pb-8">
|
||||
<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="title font-bold">{$t('forms.configuration')}</div>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-sm bg-destinations"
|
||||
class:loading={loading}
|
||||
disabled={loading}
|
||||
<button type="submit" class="btn btn-sm bg-destinations" class:loading disabled={loading}
|
||||
>{loading
|
||||
? payload.isCoolifyProxyUsed
|
||||
? $t('destination.new.saving_and_configuring_proxy')
|
||||
@ -97,12 +93,13 @@
|
||||
bind:value={payload.network}
|
||||
/>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<div class="grid grid-cols-2 items-center px-10">
|
||||
<Setting
|
||||
id="isCoolifyProxyUsed"
|
||||
bind:setting={payload.isCoolifyProxyUsed}
|
||||
on:click={() => (payload.isCoolifyProxyUsed = !payload.isCoolifyProxyUsed)}
|
||||
title={$t('destination.use_coolify_proxy')}
|
||||
description={$t('destination.new.install_proxy')}
|
||||
description={'This will install a proxy on the destination to allow you to access your applications and services without any manual configuration.'}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -259,14 +259,15 @@
|
||||
/></a
|
||||
>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<div class="grid grid-cols-2 items-center px-10">
|
||||
<Setting
|
||||
id="changeProxySetting"
|
||||
disabled={cannotDisable}
|
||||
loading={loading.proxy}
|
||||
bind:setting={destination.isCoolifyProxyUsed}
|
||||
on:click={changeProxySetting}
|
||||
title={$t('destination.use_coolify_proxy')}
|
||||
description={`This will install a proxy on the destination to allow you to access your applications and services without any manual configuration. Databases will have their own proxy. <br><br>${
|
||||
description={`This will install a proxy on the destination to allow you to access your applications and services without any manual configuration.${
|
||||
cannotDisable
|
||||
? '<span class="font-bold text-white">You cannot disable this proxy as FQDN is configured for Coolify.</span>'
|
||||
: ''
|
||||
|
@ -40,7 +40,7 @@
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
console.log(error);
|
||||
return handlerNotFoundLoad(error, url);
|
||||
}
|
||||
};
|
||||
@ -56,12 +56,16 @@
|
||||
import { errorNotification, handlerNotFoundLoad } from '$lib/common';
|
||||
import { appSession } from '$lib/store';
|
||||
import DeleteIcon from '$lib/components/DeleteIcon.svelte';
|
||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||
|
||||
const { id } = $page.params;
|
||||
const isDestinationDeletable = destination?.application.length === 0 && destination?.database.length === 0 && destination?.service.length === 0
|
||||
|
||||
const isDestinationDeletable =
|
||||
destination?.application.length === 0 &&
|
||||
destination?.database.length === 0 &&
|
||||
destination?.service.length === 0;
|
||||
|
||||
async function deleteDestination(destination: any) {
|
||||
if (!isDestinationDeletable) return
|
||||
if (!isDestinationDeletable) return;
|
||||
const sure = confirm($t('application.confirm_to_delete', { name: destination.name }));
|
||||
if (sure) {
|
||||
try {
|
||||
@ -74,12 +78,12 @@
|
||||
}
|
||||
function deletable() {
|
||||
if (!isDestinationDeletable) {
|
||||
return "Please delete all resources before deleting this."
|
||||
return 'Please delete all resources before deleting this.';
|
||||
}
|
||||
if ($appSession.isAdmin) {
|
||||
return $t('destination.delete_destination')
|
||||
return $t('destination.delete_destination');
|
||||
} else {
|
||||
return $t('destination.permission_denied_delete_destination')
|
||||
return $t('destination.permission_denied_delete_destination');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -87,14 +91,15 @@
|
||||
{#if id !== 'new'}
|
||||
<nav class="nav-side">
|
||||
<button
|
||||
id="delete"
|
||||
on:click={() => deleteDestination(destination)}
|
||||
type="submit"
|
||||
disabled={!$appSession.isAdmin && isDestinationDeletable}
|
||||
class:hover:text-red-500={$appSession.isAdmin && isDestinationDeletable}
|
||||
class="icons tooltip tooltip-primary tooltip-left bg-transparent text-sm"
|
||||
class:text-stone-600={!isDestinationDeletable}
|
||||
data-tip={deletable()}><DeleteIcon /></button
|
||||
class="icons bg-transparent text-sm"
|
||||
class:text-stone-600={!isDestinationDeletable}><DeleteIcon /></button
|
||||
>
|
||||
</nav>
|
||||
<Tooltip triggeredBy="#delete">{deletable()}</Tooltip>
|
||||
{/if}
|
||||
<slot />
|
||||
|
@ -35,6 +35,7 @@
|
||||
import DeleteIcon from '$lib/components/DeleteIcon.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import Cookies from 'js-cookie';
|
||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||
const { id } = $page.params;
|
||||
|
||||
async function deleteTeam() {
|
||||
@ -69,15 +70,14 @@
|
||||
<nav class="nav-side">
|
||||
{#if team.id !== '0'}
|
||||
<button
|
||||
id="delete"
|
||||
on:click={deleteTeam}
|
||||
type="submit"
|
||||
disabled={!$appSession.isAdmin}
|
||||
class:hover:text-red-500={$appSession.isAdmin}
|
||||
class="icons tooltip tooltip-primary tooltip-left bg-transparent text-sm"
|
||||
data-tip={$appSession.isAdmin
|
||||
? 'Delete'
|
||||
: $t('destination.permission_denied_delete_destination')}><DeleteIcon /></button
|
||||
class="icons bg-transparent text-sm"><DeleteIcon /></button
|
||||
>
|
||||
<Tooltip triggeredBy="#delete">Delete</Tooltip>
|
||||
{/if}
|
||||
</nav>
|
||||
{/if}
|
||||
|
@ -62,6 +62,7 @@
|
||||
import { errorNotification, handlerNotFoundLoad } from '$lib/common';
|
||||
import { appSession, disabledButton, status, location, setLocation } from '$lib/store';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||
const { id } = $page.params;
|
||||
|
||||
export let service: any;
|
||||
@ -108,7 +109,7 @@
|
||||
}
|
||||
async function startService() {
|
||||
$status.service.initialLoading = true;
|
||||
$status.service.loading = true
|
||||
$status.service.loading = true;
|
||||
try {
|
||||
await post(`/services/${service.id}/${service.type}/start`, {});
|
||||
} catch (error) {
|
||||
@ -152,9 +153,10 @@
|
||||
{#if service.type && service.destinationDockerId && service.version}
|
||||
{#if $location}
|
||||
<a
|
||||
id="open"
|
||||
href={$location}
|
||||
target="_blank"
|
||||
class="icons tooltip-bottom flex items-center bg-transparent text-sm"
|
||||
class="icons flex items-center bg-transparent text-sm"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6"
|
||||
@ -171,13 +173,14 @@
|
||||
<polyline points="15 4 20 4 20 9" />
|
||||
</svg></a
|
||||
>
|
||||
<Tooltip triggeredBy="#open">Open</Tooltip>
|
||||
<div class="border border-stone-700 h-8" />
|
||||
{/if}
|
||||
{#if $status.service.isExited}
|
||||
<a
|
||||
id="error"
|
||||
href={!$disabledButton ? `/services/${id}/logs` : null}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm flex items-center text-red-500 tooltip-error"
|
||||
data-tip="Service exited with an error!"
|
||||
class="icons bg-transparent text-sm flex items-center text-red-500 tooltip-error"
|
||||
sveltekit:prefetch
|
||||
>
|
||||
<svg
|
||||
@ -198,10 +201,11 @@
|
||||
<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 tooltip-bottom flex animate-spin items-center space-x-2 bg-transparent text-sm duration-500 ease-in-out"
|
||||
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"
|
||||
@ -224,13 +228,11 @@
|
||||
</button>
|
||||
{:else if $status.service.isRunning}
|
||||
<button
|
||||
id="stop"
|
||||
on:click={stopService}
|
||||
type="submit"
|
||||
disabled={$disabledButton}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm flex items-center space-x-2 text-red-500"
|
||||
data-tip={$appSession.isAdmin
|
||||
? $t('service.stop_service')
|
||||
: $t('service.permission_denied_stop_service')}
|
||||
class="icons bg-transparent text-sm flex items-center space-x-2 text-red-500"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -247,15 +249,14 @@
|
||||
<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={$disabledButton}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm flex items-center space-x-2 text-green-500"
|
||||
data-tip={$appSession.isAdmin
|
||||
? $t('service.start_service')
|
||||
: $t('service.permission_denied_start_service')}
|
||||
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"
|
||||
@ -270,21 +271,20 @@
|
||||
<path d="M7 4v16l13 -8z" />
|
||||
</svg>
|
||||
</button>
|
||||
<Tooltip triggeredBy="#start">Start</Tooltip>
|
||||
{/if}
|
||||
<div class="border border-stone-700 h-8" />
|
||||
{/if}
|
||||
{#if service.type && service.destinationDockerId && service.version}
|
||||
<a
|
||||
id="configuration"
|
||||
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
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm disabled:text-red-500"
|
||||
data-tip={$t('application.configurations')}
|
||||
>
|
||||
<button class="icons bg-transparent text-sm disabled:text-red-500">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6"
|
||||
@ -308,17 +308,16 @@
|
||||
</svg></button
|
||||
></a
|
||||
>
|
||||
<Tooltip triggeredBy="#configuration">Configuration</Tooltip>
|
||||
<a
|
||||
id="secrets"
|
||||
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
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm disabled:text-red-500"
|
||||
data-tip={$t('application.secret')}
|
||||
>
|
||||
<button class="icons bg-transparent text-sm disabled:text-red-500">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-6 h-6"
|
||||
@ -338,17 +337,16 @@
|
||||
</svg></button
|
||||
></a
|
||||
>
|
||||
<Tooltip triggeredBy="#secrets">Secrets</Tooltip>
|
||||
<a
|
||||
id="persistentstorage"
|
||||
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
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm disabled:text-red-500"
|
||||
data-tip="Persistent Storage"
|
||||
>
|
||||
<button class="icons bg-transparent text-sm disabled:text-red-500">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-6 h-6"
|
||||
@ -366,19 +364,17 @@
|
||||
</svg>
|
||||
</button></a
|
||||
>
|
||||
<Tooltip triggeredBy="#persistentstorage">Persistent Storage</Tooltip>
|
||||
<div class="border border-stone-700 h-8" />
|
||||
<a
|
||||
id="logs"
|
||||
href={!$disabledButton && $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
|
||||
disabled={!$status.service.isRunning}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm"
|
||||
data-tip={$t('service.logs')}
|
||||
>
|
||||
<button disabled={!$status.service.isRunning} class="icons bg-transparent text-sm">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6"
|
||||
@ -398,16 +394,16 @@
|
||||
</svg></button
|
||||
></a
|
||||
>
|
||||
<Tooltip triggeredBy="#logs">Logs</Tooltip>
|
||||
{/if}
|
||||
<button
|
||||
id="delete"
|
||||
on:click={deleteService}
|
||||
type="submit"
|
||||
disabled={!$appSession.isAdmin}
|
||||
class:hover:text-red-500={$appSession.isAdmin}
|
||||
class="icons bg-transparent tooltip tooltip-primary tooltip-bottom text-sm"
|
||||
data-tip={$appSession.isAdmin
|
||||
? $t('service.delete_service')
|
||||
: $t('service.permission_denied_delete_service')}><DeleteIcon /></button
|
||||
class="icons bg-transparent text-sm"><DeleteIcon /></button
|
||||
>
|
||||
<Tooltip triggeredBy="#delete">Delete</Tooltip>
|
||||
</nav>
|
||||
<slot />
|
||||
|
@ -5,6 +5,7 @@
|
||||
import { t } from '$lib/translations';
|
||||
import { errorNotification } from '$lib/common';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||
|
||||
let service: any = {};
|
||||
let logsLoading = false;
|
||||
@ -126,9 +127,9 @@
|
||||
{/if}
|
||||
<div class="flex justify-end sticky top-0 p-1 mx-1">
|
||||
<button
|
||||
id="follow"
|
||||
on:click={followBuild}
|
||||
class="bg-transparent btn btn-sm tooltip tooltip-primary tooltip-bottom"
|
||||
data-tip="Follow logs"
|
||||
class="bg-transparent btn btn-sm"
|
||||
class:text-green-500={followingLogs}
|
||||
>
|
||||
<svg
|
||||
@ -148,6 +149,7 @@
|
||||
<line x1="16" y1="12" x2="12" y2="16" />
|
||||
</svg>
|
||||
</button>
|
||||
<Tooltip triggeredBy="#follow">Follow Logs</Tooltip>
|
||||
</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"
|
||||
|
@ -26,6 +26,7 @@
|
||||
import { addToast, appSession, features } from '$lib/store';
|
||||
import { errorNotification, getDomain } from '$lib/common';
|
||||
import Menu from './_Menu.svelte';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
|
||||
let isRegistrationEnabled = settings.isRegistrationEnabled;
|
||||
let dualCerts = settings.dualCerts;
|
||||
@ -195,8 +196,8 @@
|
||||
<div class="flex-col">
|
||||
<div class="pt-2 text-base font-bold text-stone-100">
|
||||
{$t('application.url_fqdn')}
|
||||
<DocLink explanation={$t('setting.ssl_explainer')} />
|
||||
</div>
|
||||
<Explainer text={$t('setting.ssl_explainer')} />
|
||||
</div>
|
||||
<div class="justify-start text-left">
|
||||
<input
|
||||
@ -250,8 +251,8 @@
|
||||
<div class="flex-col">
|
||||
<div class="pt-2 text-base font-bold text-stone-100">
|
||||
{$t('forms.public_port_range')}
|
||||
<DocLink explanation={$t('forms.public_port_range_explainer')} />
|
||||
</div>
|
||||
<Explainer text={$t('forms.public_port_range_explainer')} />
|
||||
</div>
|
||||
<div class="mx-auto flex-row items-center justify-center space-y-2">
|
||||
<input
|
||||
@ -273,6 +274,7 @@
|
||||
</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')}
|
||||
@ -280,18 +282,19 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<div class="flex-col">
|
||||
<div class="pt-2 text-base font-bold text-stone-100">
|
||||
Custom DNS servers
|
||||
</div>
|
||||
<Explainer text="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 class="text-base font-bold text-stone-100">
|
||||
Custom DNS servers <DocLink
|
||||
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="mx-auto flex-row items-center justify-center space-y-2">
|
||||
|
||||
<div class="flex-row items-center justify-center">
|
||||
<input placeholder="1.1.1.1,8.8.8.8" bind:value={DNSServers} />
|
||||
</div>
|
||||
</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}
|
||||
|
@ -8,6 +8,7 @@
|
||||
import { dashify, errorNotification, getDomain } from '$lib/common';
|
||||
import { addToast, appSession } from '$lib/store';
|
||||
import { dev } from '$app/env';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
|
||||
const { id } = $page.params;
|
||||
|
||||
@ -115,7 +116,9 @@
|
||||
<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</label>
|
||||
<label for="customPort" class="text-base font-bold text-stone-100">Custom SSH Port <DocLink
|
||||
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"
|
||||
@ -124,18 +127,15 @@
|
||||
required
|
||||
value={source.customPort}
|
||||
/>
|
||||
<Explainer
|
||||
text="If you use a self-hosted version of Git, you can provide custom port for all the Git related actions."
|
||||
/>
|
||||
</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</label
|
||||
>Organization
|
||||
<DocLink
|
||||
explanation={"Fill it if you would like to use an organization's as your Git Source. Otherwise your user will be used."}
|
||||
/></label
|
||||
>
|
||||
<Explainer
|
||||
text="Fill it if you would like to use an organization's as your Git Source. Otherwise your user will be used."
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
name="organization"
|
||||
|
@ -11,6 +11,7 @@
|
||||
import { t } from '$lib/translations';
|
||||
import { errorNotification } from '$lib/common';
|
||||
import { addToast, appSession } from '$lib/store';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
const { id } = $page.params;
|
||||
|
||||
let url = settings.fqdn ? settings.fqdn : window.location.origin;
|
||||
@ -148,10 +149,8 @@
|
||||
<div class="flex space-x-1 pb-7">
|
||||
<div class="title">General</div>
|
||||
{#if $appSession.isAdmin}
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-sm bg-sources"
|
||||
disabled={loading}>{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}
|
||||
@ -166,16 +165,12 @@
|
||||
</div>
|
||||
<div class="grid grid-flow-row gap-2 px-10">
|
||||
{#if !source.gitlabAppId}
|
||||
<Explainer
|
||||
customClass="w-full"
|
||||
text="<span class='font-bold text-base text-white'>Scopes required:</span>
|
||||
<br>- <span class='text-sources font-bold'>api</span> (Access the authenticated user's API)
|
||||
<br>- <span class='text-sources font-bold'>read_repository</span> (Allows read-only access to the repository)
|
||||
<br>- <span class='text-sources font-bold'>email</span> (Allows read-only access to the user's primary email address using OpenID Connect)
|
||||
<br>
|
||||
<br>For extra security, you can set <span class='text-sources font-bold'>Expire Access Tokens</span>
|
||||
<br><br>Webhook URL: <span class='text-sources font-bold'>{url}/webhooks/gitlab</span>"
|
||||
/>
|
||||
<a
|
||||
href="https://docs.coollabs.io/coolify/sources#how-to-integrate-with-gitlab"
|
||||
class="font-bold "
|
||||
target="_blank"
|
||||
rel="noopener noreferrer">Documentation and detailed instructions.</a
|
||||
>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<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}>
|
||||
@ -245,7 +240,11 @@
|
||||
</div>
|
||||
{#if selfHosted}
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="customPort" class="text-base font-bold text-stone-100">Custom SSH Port</label>
|
||||
<label for="customPort" class="text-base font-bold text-stone-100"
|
||||
>Custom SSH Port <DocLink
|
||||
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"
|
||||
@ -254,19 +253,16 @@
|
||||
required
|
||||
bind:value={source.customPort}
|
||||
/>
|
||||
<Explainer
|
||||
text="If you use a self-hosted version of Git, you can provide custom port for all the Git related actions."
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="grid grid-cols-2 items-start">
|
||||
<div class="flex-col">
|
||||
<label for="oauthId" class="pt-2 text-base font-bold text-stone-100"
|
||||
>{$t('source.oauth_id')}</label
|
||||
>{$t('source.oauth_id')}
|
||||
{#if !source.gitlabAppId}
|
||||
<DocLink explanation={$t('source.oauth_id_explainer')} />
|
||||
{/if}</label
|
||||
>
|
||||
{#if !source.gitlabAppId}
|
||||
<Explainer text={$t('source.oauth_id_explainer')} />
|
||||
{/if}
|
||||
</div>
|
||||
<input
|
||||
disabled={source.gitlabAppId}
|
||||
|
@ -37,6 +37,7 @@
|
||||
import { appSession } from '$lib/store';
|
||||
import DeleteIcon from '$lib/components/DeleteIcon.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||
const { id } = $page.params;
|
||||
|
||||
async function deleteSource(name: string) {
|
||||
@ -55,15 +56,14 @@
|
||||
{#if id !== 'new'}
|
||||
<nav class="nav-side">
|
||||
<button
|
||||
id="delete"
|
||||
on:click={() => deleteSource(source.name)}
|
||||
type="submit"
|
||||
disabled={!$appSession.isAdmin}
|
||||
class:hover:text-red-500={$appSession.isAdmin}
|
||||
class="icons tooltip tooltip-primary tooltip-bottom bg-transparent text-sm"
|
||||
data-tip={$appSession.isAdmin
|
||||
? $t('source.delete_git_source')
|
||||
: $t('source.permission_denied')}><DeleteIcon /></button
|
||||
class="icons bg-transparent text-sm"><DeleteIcon /></button
|
||||
>
|
||||
</nav>
|
||||
<Tooltip triggeredBy="#delete">Delete</Tooltip>
|
||||
{/if}
|
||||
<slot />
|
||||
|
@ -1,15 +1,15 @@
|
||||
const defaultTheme = require('tailwindcss/defaultTheme');
|
||||
|
||||
module.exports = {
|
||||
content: ['./**/*.html', './src/**/*.{js,jsx,ts,tsx,svelte}'],
|
||||
important: true,
|
||||
content: ['./**/*.html', './src/**/*.{js,jsx,ts,tsx,svelte}', "./node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}",],
|
||||
important: true,
|
||||
daisyui: {
|
||||
themes: [
|
||||
{
|
||||
coollabs: {
|
||||
"base-100":"#323232",
|
||||
"base-200":"#242424",
|
||||
"base-300":"#181818",
|
||||
"base-100": "#323232",
|
||||
"base-200": "#242424",
|
||||
"base-300": "#181818",
|
||||
"primary": "#6d28d9",
|
||||
"primary-content": "#fff",
|
||||
"secondary": "#343232",
|
||||
@ -40,13 +40,13 @@ module.exports = {
|
||||
sans: ['Poppins', ...defaultTheme.fontFamily.sans]
|
||||
},
|
||||
colors: {
|
||||
"applications":"#16A34A",
|
||||
"databases":"#9333EA",
|
||||
"destinations":"#0284C7",
|
||||
"sources":"#EA580C",
|
||||
"services":"#DB2777",
|
||||
"settings":"#FEE440",
|
||||
"iam":"#C026D3",
|
||||
"applications": "#16A34A",
|
||||
"databases": "#9333EA",
|
||||
"destinations": "#0284C7",
|
||||
"sources": "#EA580C",
|
||||
"services": "#DB2777",
|
||||
"settings": "#FEE440",
|
||||
"iam": "#C026D3",
|
||||
coollabs: '#6B16ED',
|
||||
'coollabs-100': '#7317FF',
|
||||
coolblack: '#161616',
|
||||
@ -62,5 +62,6 @@ module.exports = {
|
||||
scrollbar: ['dark'],
|
||||
extend: {}
|
||||
},
|
||||
darkMode: 'class',
|
||||
plugins: [require('tailwindcss-scrollbar'), require('daisyui'), require("@tailwindcss/typography")]
|
||||
};
|
||||
|
55
pnpm-lock.yaml
generated
55
pnpm-lock.yaml
generated
@ -131,7 +131,9 @@ importers:
|
||||
|
||||
apps/ui:
|
||||
specifiers:
|
||||
'@floating-ui/dom': ^1.0.1
|
||||
'@playwright/test': 1.25.1
|
||||
'@popperjs/core': ^2.11.6
|
||||
'@sveltejs/adapter-static': 1.0.0-next.39
|
||||
'@sveltejs/kit': 1.0.0-next.405
|
||||
'@tailwindcss/typography': ^0.5.4
|
||||
@ -139,11 +141,14 @@ importers:
|
||||
'@typescript-eslint/eslint-plugin': 5.35.1
|
||||
'@typescript-eslint/parser': 5.35.1
|
||||
autoprefixer: 10.4.8
|
||||
classnames: ^2.3.1
|
||||
cuid: 2.1.8
|
||||
daisyui: 2.24.0
|
||||
eslint: 8.22.0
|
||||
eslint-config-prettier: 8.5.0
|
||||
eslint-plugin-svelte3: 4.0.0
|
||||
flowbite: ^1.5.2
|
||||
flowbite-svelte: ^0.26.2
|
||||
js-cookie: 3.0.1
|
||||
p-limit: 4.0.0
|
||||
postcss: 8.4.16
|
||||
@ -169,15 +174,20 @@ importers:
|
||||
svelte-select: 4.4.7
|
||||
sveltekit-i18n: 2.2.2_svelte@3.49.0
|
||||
devDependencies:
|
||||
'@floating-ui/dom': 1.0.1
|
||||
'@playwright/test': 1.25.1
|
||||
'@popperjs/core': 2.11.6
|
||||
'@sveltejs/kit': 1.0.0-next.405_svelte@3.49.0+vite@3.0.5
|
||||
'@types/js-cookie': 3.0.2
|
||||
'@typescript-eslint/eslint-plugin': 5.35.1_ktjxjibzrfqejavile4bhmzhjq
|
||||
'@typescript-eslint/parser': 5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq
|
||||
autoprefixer: 10.4.8_postcss@8.4.16
|
||||
classnames: 2.3.1
|
||||
eslint: 8.22.0
|
||||
eslint-config-prettier: 8.5.0_eslint@8.22.0
|
||||
eslint-plugin-svelte3: 4.0.0_laaqauvsmoyypsiqkozwyi2fn4
|
||||
flowbite: 1.5.2
|
||||
flowbite-svelte: 0.26.2
|
||||
postcss: 8.4.16
|
||||
prettier: 2.7.1
|
||||
prettier-plugin-svelte: 2.7.0_o3ioganyptcsrh6x4hnxvjkpqi
|
||||
@ -369,6 +379,16 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@floating-ui/core/1.0.1:
|
||||
resolution: {integrity: sha512-bO37brCPfteXQfFY0DyNDGB3+IMe4j150KFQcgJ5aBP295p9nBGeHEs/p0czrRbtlHq4Px/yoPXO/+dOCcF4uA==}
|
||||
dev: true
|
||||
|
||||
/@floating-ui/dom/1.0.1:
|
||||
resolution: {integrity: sha512-wBDiLUKWU8QNPNOTAFHiIAkBv1KlHauG2AhqjSeh2H+wR8PX+AArXfz8NkRexH5PgMJMmSOS70YS89AbWYh5dA==}
|
||||
dependencies:
|
||||
'@floating-ui/core': 1.0.1
|
||||
dev: true
|
||||
|
||||
/@humanwhocodes/config-array/0.10.4:
|
||||
resolution: {integrity: sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==}
|
||||
engines: {node: '>=10.10.0'}
|
||||
@ -458,6 +478,10 @@ packages:
|
||||
playwright-core: 1.25.1
|
||||
dev: true
|
||||
|
||||
/@popperjs/core/2.11.6:
|
||||
resolution: {integrity: sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==}
|
||||
dev: true
|
||||
|
||||
/@prisma/client/3.15.2_prisma@3.15.2:
|
||||
resolution: {integrity: sha512-ErqtwhX12ubPhU4d++30uFY/rPcyvjk+mdifaZO5SeM21zS3t4jQrscy8+6IyB0GIYshl5ldTq6JSBo1d63i8w==}
|
||||
engines: {node: '>=12.6'}
|
||||
@ -2000,6 +2024,10 @@ packages:
|
||||
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
|
||||
dev: false
|
||||
|
||||
/classnames/2.3.1:
|
||||
resolution: {integrity: sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==}
|
||||
dev: true
|
||||
|
||||
/clean-stack/4.2.0:
|
||||
resolution: {integrity: sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==}
|
||||
engines: {node: '>=12'}
|
||||
@ -3461,6 +3489,24 @@ packages:
|
||||
resolution: {integrity: sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==}
|
||||
dev: true
|
||||
|
||||
/flowbite-svelte/0.26.2:
|
||||
resolution: {integrity: sha512-CpZ33fyMuzrYvECKN2rD5zNa/ZY0c4cDMcY6wE/hvajFybbCqwMYzd0AkA88zTNm5fknEN0/E23TVmD4Qkhzzw==}
|
||||
engines: {node: '>=16.0.0', npm: '>=7.0.0'}
|
||||
dependencies:
|
||||
'@floating-ui/dom': 1.0.1
|
||||
'@popperjs/core': 2.11.6
|
||||
classnames: 2.3.1
|
||||
flowbite: 1.5.2
|
||||
svelte-heros: 2.3.5
|
||||
dev: true
|
||||
|
||||
/flowbite/1.5.2:
|
||||
resolution: {integrity: sha512-oSKhPkg0bYb4dZG4ypSh++dPrFM3IOSER6HOwJHYRFPW5u9PXL4AQFMQh7Kytgws2xrDQyl/zqefZmymeWt2IA==}
|
||||
dependencies:
|
||||
'@popperjs/core': 2.11.6
|
||||
mini-svg-data-uri: 1.4.4
|
||||
dev: true
|
||||
|
||||
/follow-redirects/1.15.0:
|
||||
resolution: {integrity: sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==}
|
||||
engines: {node: '>=4.0'}
|
||||
@ -4482,6 +4528,11 @@ packages:
|
||||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/mini-svg-data-uri/1.4.4:
|
||||
resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/minimalistic-assert/1.0.1:
|
||||
resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==}
|
||||
dev: false
|
||||
@ -5856,6 +5907,10 @@ packages:
|
||||
- sugarss
|
||||
dev: true
|
||||
|
||||
/svelte-heros/2.3.5:
|
||||
resolution: {integrity: sha512-08PdccaeRPP1pVa90AGieTwGzrNtXpC1Fry+i95OTvcR3xbGRU/hxK4rnaFYvGgk1Pxj9YT6GKGTEX8uXE9XJQ==}
|
||||
dev: true
|
||||
|
||||
/svelte-hmr/0.14.12_svelte@3.49.0:
|
||||
resolution: {integrity: sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w==}
|
||||
engines: {node: ^12.20 || ^14.13.1 || >= 16}
|
||||
|
Loading…
x
Reference in New Issue
Block a user