* New Version: 3.0.0
This commit is contained in:
Andras Bacsai
2022-07-06 11:02:36 +02:00
committed by GitHub
parent 9137e8bc32
commit 87ba4560ad
491 changed files with 16824 additions and 20459 deletions

View File

@@ -0,0 +1,183 @@
<script lang="ts">
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
import { t } from '$lib/translations';
import Select from 'svelte-select';
export let service: any;
export let readOnly: any;
let mailgunRegions = [
{
value: 'EU',
label: 'EU'
},
{
value: 'US',
label: 'US'
}
];
</script>
<div class="flex space-x-1 py-5 font-bold">
<div class="title">Fider</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="jwtSecret">JWT Secret</label>
<CopyPasswordField
name="jwtSecret"
id="jwtSecret"
isPasswordField
value={service.fider.jwtSecret}
readonly
disabled
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="emailNoreply">Noreply Email</label>
<input
name="emailNoreply"
id="emailNoreply"
type="email"
required
readonly={readOnly}
disabled={readOnly}
bind:value={service.fider.emailNoreply}
placeholder="{$t('forms.eg')}: noreply@yourdomain.com"
/>
</div>
<div class="flex space-x-1 py-5 font-bold">
<div class="title">Email</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="emailMailgunApiKey">Mailgun API Key</label>
<CopyPasswordField
name="emailMailgunApiKey"
id="emailMailgunApiKey"
isPasswordField
bind:value={service.fider.emailMailgunApiKey}
readonly={readOnly}
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 class="flex space-x-1 py-5 px-10 font-bold">
<div class="text-lg">Or</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="emailSmtpHost">SMTP Host</label>
<input
name="emailSmtpHost"
id="emailSmtpHost"
readonly={readOnly}
disabled={readOnly}
bind:value={service.fider.emailSmtpHost}
placeholder="{$t('forms.eg')}: smtp.yourdomain.com"
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="emailSmtpPort">SMTP Port</label>
<input
name="emailSmtpPort"
id="emailSmtpPort"
readonly={readOnly}
disabled={readOnly}
bind:value={service.fider.emailSmtpPort}
placeholder="{$t('forms.eg')}: 587"
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="emailSmtpUser">SMTP User</label>
<input
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 px-10">
<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 px-10">
<label for="emailSmtpEnableStartTls">SMTP Start TLS</label>
<input
name="emailSmtpEnableStartTls"
id="emailSmtpEnableStartTls"
readonly={readOnly}
disabled={readOnly}
bind:value={service.fider.emailSmtpEnableStartTls}
placeholder="{$t('forms.eg')}: true"
/>
</div>
<div class="flex space-x-1 py-5 font-bold">
<div class="title">PostgreSQL</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="postgresqlUser">{$t('forms.username')}</label>
<CopyPasswordField
name="postgresqlUser"
id="postgresqlUser"
value={service.fider.postgresqlUser}
readonly
disabled
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="postgresqlPassword">{$t('forms.password')}</label>
<CopyPasswordField
id="postgresqlPassword"
isPasswordField
readonly
disabled
name="postgresqlPassword"
value={service.fider.postgresqlPassword}
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="postgresqlDatabase">{$t('index.database')}</label>
<CopyPasswordField
name="postgresqlDatabase"
id="postgresqlDatabase"
value={service.fider.postgresqlDatabase}
readonly
disabled
/>
</div>

View File

@@ -0,0 +1,90 @@
<script lang="ts">
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
import { t } from '$lib/translations';
export let readOnly: any;
export let service: any;
</script>
<div class="flex space-x-1 py-5 font-bold">
<div class="title">Ghost</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="email">{$t('forms.default_email_address')}</label>
<input
name="email"
id="email"
disabled
readonly
placeholder={$t('forms.email')}
value={service.ghost.defaultEmail}
required
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="defaultPassword">{$t('forms.default_password')}</label>
<CopyPasswordField
id="defaultPassword"
isPasswordField
readonly
disabled
name="defaultPassword"
value={service.ghost.defaultPassword}
/>
</div>
<div class="flex space-x-1 py-5 font-bold">
<div class="title">MariaDB</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="mariadbUser">{$t('forms.username')}</label>
<CopyPasswordField
name="mariadbUser"
id="mariadbUser"
value={service.ghost.mariadbUser}
readonly
disabled
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="mariadbPassword">{$t('forms.password')}</label>
<CopyPasswordField
id="mariadbPassword"
isPasswordField
readonly
disabled
name="mariadbPassword"
value={service.ghost.mariadbPassword}
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="mariadbDatabase">{$t('index.database')}</label>
<input
name="mariadbDatabase"
id="mariadbDatabase"
required
readonly={readOnly}
disabled={readOnly}
bind:value={service.ghost.mariadbDatabase}
placeholder="{$t('forms.eg')}: ghost_db"
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="mariadbRootUser">{$t('forms.root_db_user')}</label>
<CopyPasswordField
id="mariadbRootUser"
readonly
disabled
name="mariadbRootUser"
value={service.ghost.mariadbRootUser}
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="mariadbRootUserPassword">{$t('forms.root_db_password')}</label>
<CopyPasswordField
id="mariadbRootUserPassword"
isPasswordField
readonly
disabled
name="mariadbRootUserPassword"
value={service.ghost.mariadbRootUserPassword}
/>
</div>

View File

@@ -0,0 +1,58 @@
<script lang="ts">
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
import Explainer from '$lib/components/Explainer.svelte';
import { t } from '$lib/translations';
export let service: any;
</script>
<div class="flex space-x-1 py-5 font-bold">
<div class="title">Hasura</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="graphQLAdminPassword">GraphQL Admin Password</label>
<CopyPasswordField
name="graphQLAdminPassword"
id="graphQLAdminPassword"
isPasswordField
value={service.hasura.graphQLAdminPassword}
readonly
disabled
/>
</div>
<div class="flex space-x-1 py-5 font-bold">
<div class="title">PostgreSQL</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="postgresqlUser">{$t('forms.username')}</label>
<CopyPasswordField
name="postgresqlUser"
id="postgresqlUser"
value={service.hasura.postgresqlUser}
readonly
disabled
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="postgresqlPassword">{$t('forms.password')}</label>
<CopyPasswordField
id="postgresqlPassword"
isPasswordField
readonly
disabled
name="postgresqlPassword"
value={service.hasura.postgresqlPassword}
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="postgresqlDatabase">{$t('index.database')}</label>
<CopyPasswordField
name="postgresqlDatabase"
id="postgresqlDatabase"
value={service.hasura.postgresqlDatabase}
readonly
disabled
/>
</div>

View File

@@ -0,0 +1,20 @@
<script lang="ts">
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
import { t } from '$lib/translations';
export let service: any;
</script>
<div class="flex space-x-1 py-5 font-bold">
<div class="title">MeiliSearch</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="masterKey">{$t('forms.admin_api_key')}</label>
<CopyPasswordField
id="masterKey"
isPasswordField
readonly
disabled
name="masterKey"
value={service.meiliSearch.masterKey}
/>
</div>

View File

@@ -0,0 +1,45 @@
<script lang="ts">
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
import { t } from '$lib/translations';
export let service: any;
</script>
<div class="flex space-x-1 py-5 font-bold">
<div class="title">MinIO</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="rootUser">{$t('forms.root_user')}</label>
<input
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
name="publicPort"
id="publicPort"
value={service.minio.publicPort}
disabled
readonly
placeholder={$t('forms.generated_automatically_after_start')}
/>
</div>
{/if}

View File

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

View File

@@ -0,0 +1,277 @@
<script lang="ts">
export let service: any;
export let readOnly: any;
export let settings: any;
import cuid from 'cuid';
import { onMount } from 'svelte';
import { browser } from '$app/env';
import { page } from '$app/stores';
import { toast } from '@zerodevx/svelte-toast';
import { get, post } from '$lib/api';
import { errorNotification } from '$lib/common';
import { t } from '$lib/translations';
import { appSession, disabledButton, status } from '$lib/store';
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
import Explainer from '$lib/components/Explainer.svelte';
import Setting from '$lib/components/Setting.svelte'
import Fider from './_Fider.svelte';
import Ghost from './_Ghost.svelte';
import Hasura from './_Hasura.svelte';
import MeiliSearch from './_MeiliSearch.svelte';
import MinIo from './_MinIO.svelte';
import PlausibleAnalytics from './_PlausibleAnalytics.svelte';
import Umami from './_Umami.svelte';
import VsCodeServer from './_VSCodeServer.svelte';
import Wordpress from './_Wordpress.svelte';
const { id } = $page.params;
let loading = false;
let loadingVerification = false;
let dualCerts = service.dualCerts;
async function handleSubmit() {
if (loading) return;
loading = true;
try {
await post(`/services/${id}/check`, {
fqdn: service.fqdn,
otherFqdns: service.minio?.apiFqdn ? [service.minio?.apiFqdn] : [],
exposePort: service.exposePort
});
await post(`/services/${id}`, { ...service });
$disabledButton = false;
toast.push('Settings saved.');
} catch (error) {
return errorNotification(error);
} finally {
loading = false;
}
}
async function setEmailsToVerified() {
loadingVerification = true;
try {
await post(`/services/${id}/${service.type}/activate`, { id: service.id });
toast.push(t.get('services.all_email_verified'));
} catch (error) {
return errorNotification(error);
} finally {
loadingVerification = false;
}
}
async function changeSettings(name: any) {
try {
if (name === 'dualCerts') {
dualCerts = !dualCerts;
}
await post(`/services/${id}/settings`, { dualCerts });
return toast.push(t.get('application.settings_saved'));
} catch (error) {
return errorNotification(error);
}
}
onMount(async () => {
if (browser && window.location.hostname === 'demo.coolify.io' && !service.fqdn) {
service.fqdn = `http://${cuid()}.demo.coolify.io`;
if (service.type === 'wordpress') {
service.wordpress.mysqlDatabase = 'db';
}
if (service.type === 'plausibleanalytics') {
service.plausibleAnalytics.email = 'noreply@demo.com';
service.plausibleAnalytics.username = 'admin';
}
if (service.type === 'minio') {
service.minio.apiFqdn = `http://${cuid()}.demo.coolify.io`;
}
if (service.type === 'ghost') {
service.ghost.mariadbDatabase = 'db';
}
if (service.type === 'fider') {
service.fider.emailNoreply = 'noreply@demo.com';
}
await handleSubmit();
}
});
</script>
<div class="mx-auto max-w-4xl px-6 pb-12">
<form on:submit|preventDefault={handleSubmit} class="py-4">
<div class="flex space-x-1 pb-5 font-bold">
<div class="title">{$t('general')}</div>
{#if $appSession.isAdmin}
<button
type="submit"
class:bg-pink-600={!loading}
class:hover:bg-pink-500={!loading}
disabled={loading}>{loading ? $t('forms.saving') : $t('forms.save')}</button
>
{/if}
{#if service.type === 'plausibleanalytics' && $status.service.isRunning}
<button on:click|preventDefault={setEmailsToVerified} disabled={loadingVerification}
>{loadingVerification
? $t('forms.verifying')
: $t('forms.verify_emails_without_smtp')}</button
>
{/if}
</div>
<div class="grid grid-flow-row gap-2">
{#if service.type === 'minio' && !service.minio.apiFqdn && $status.service.isRunning}
<div class="text-center">
<span class="font-bold text-red-500">IMPORTANT!</span> There was a small modification with
Minio in the latest version of Coolify. Now you can separate the Console URL from the API URL,
so you could use both through SSL. But this proccess cannot be done automatically, so you have
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 class="grid grid-cols-2 items-center px-10">
<label for="version" class="text-base font-bold text-stone-100">Version / Tag</label>
<a
href={$appSession.isAdmin && !$status.service.isRunning
? `/services/${id}/configuration/version?from=/services/${id}`
: ''}
class="no-underline"
>
<input
value={service.version}
id="service"
disabled={$status.service.isRunning}
class:cursor-pointer={!$status.service.isRunning}
/></a
>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="destination" class="text-base font-bold text-stone-100"
>{$t('application.destination')}</label
>
<div>
{#if service.destinationDockerId}
<div class="no-underline">
<input
value={service.destinationDocker.name}
id="destination"
disabled
class="bg-transparent "
/>
</div>
{/if}
</div>
</div>
{#if service.type === 'minio'}
<div class="grid grid-cols-2 px-10">
<div class="flex-col ">
<label for="fqdn" class="pt-2 text-base font-bold text-stone-100">Console URL</label>
</div>
<CopyPasswordField
placeholder="eg: https://console.min.io"
readonly={!$appSession.isAdmin && !$status.service.isRunning}
disabled={!$appSession.isAdmin || $status.service.isRunning}
name="fqdn"
id="fqdn"
pattern="^https?://([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{'{'}2,{'}'}$"
bind:value={service.fqdn}
required
/>
</div>
<div class="grid grid-cols-2 px-10">
<div class="flex-col ">
<label for="apiFqdn" class="pt-2 text-base font-bold text-stone-100">API URL</label>
<Explainer text={$t('application.https_explainer')} />
</div>
<CopyPasswordField
placeholder="eg: https://min.io"
readonly={!$appSession.isAdmin && !$status.service.isRunning}
disabled={!$appSession.isAdmin || $status.service.isRunning}
name="apiFqdn"
id="apiFqdn"
pattern="^https?://([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{'{'}2,{'}'}$"
bind:value={service.minio.apiFqdn}
required
/>
</div>
{:else}
<div class="grid grid-cols-2 px-10">
<div class="flex-col ">
<label for="fqdn" class="pt-2 text-base font-bold text-stone-100"
>{$t('application.url_fqdn')}</label
>
<Explainer text={$t('application.https_explainer')} />
</div>
<CopyPasswordField
placeholder="eg: https://analytics.coollabs.io"
readonly={!$appSession.isAdmin && !$status.service.isRunning}
disabled={!$appSession.isAdmin || $status.service.isRunning}
name="fqdn"
id="fqdn"
pattern="^https?://([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{'{'}2,{'}'}$"
bind:value={service.fqdn}
required
/>
</div>
{/if}
<div class="grid grid-cols-2 items-center px-10">
<Setting
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 class="grid grid-cols-2 items-center px-10">
<label for="exposePort" class="text-base font-bold text-stone-100">Exposed Port</label>
<input
readonly={!$appSession.isAdmin && !$status.service.isRunning}
disabled={!$appSession.isAdmin || $status.service.isRunning}
name="exposePort"
id="exposePort"
bind:value={service.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 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} />
{/if}
</div>
</form>
</div>

View File

@@ -0,0 +1,29 @@
<script lang="ts">
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
import Explainer from '$lib/components/Explainer.svelte';
export let service: any;
</script>
<div class="flex space-x-1 py-5 font-bold">
<div class="title">Umami</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="adminUser">Admin User</label>
<input name="adminUser" id="adminUser" placeholder="admin" value="admin" disabled readonly />
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="umamiAdminPassword">Initial Admin Password</label>
<CopyPasswordField
isPasswordField
name="umamiAdminPassword"
id="umamiAdminPassword"
placeholder="admin"
value={service.umami.umamiAdminPassword}
disabled
readonly
/>
<Explainer
text="It could be changed in Umami. <br>This is just the password set initially after the first start."
/>
</div>

View File

@@ -0,0 +1,21 @@
<script lang="ts">
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
import { t } from '$lib/translations';
export let service: any;
</script>
<div class="flex space-x-1 py-5 font-bold">
<div class="title">VSCode Server</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="password">{$t('forms.password')}</label>
<CopyPasswordField
id="password"
isPasswordField
readonly
disabled
name="password"
value={service.vscodeserver.password}
/>
</div>

View File

@@ -0,0 +1,213 @@
<script lang="ts">
import { post } from '$lib/api';
import { page } from '$app/stores';
import { status } from '$lib/store';
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
import Setting from '$lib/components/Setting.svelte';
import { browser } from '$app/env';
import { t } from '$lib/translations';
import { errorNotification, getDomain } from '$lib/common';
export let service: any;
export let readOnly: any;
export let settings: any;
const { id } = $page.params;
let ftpUrl = generateUrl(service.wordpress.ftpPublicPort);
let ftpUser = service.wordpress.ftpUser;
let ftpPassword = service.wordpress.ftpPassword;
let ftpLoading = false;
let ownMysql = service.wordpress.ownMysql;
function generateUrl(publicPort: any) {
return browser
? `sftp://${
settings.fqdn ? getDomain(settings.fqdn) : window.location.hostname
}:${publicPort}`
: 'Loading...';
}
async function changeSettings(name: any) {
if (ftpLoading) return;
if ($status.service.isRunning) {
ftpLoading = true;
let ftpEnabled = service.wordpress.ftpEnabled;
if (name === 'ftpEnabled') {
ftpEnabled = !ftpEnabled;
}
try {
const {
publicPort,
ftpUser: user,
ftpPassword: password
} = await post(`/services/${id}/wordpress/ftp`, {
ftpEnabled
});
ftpUrl = generateUrl(publicPort);
ftpUser = user;
ftpPassword = password;
service.wordpress.ftpEnabled = ftpEnabled;
} catch (error) {
return errorNotification(error);
} finally {
ftpLoading = false;
}
} else {
try {
if (name === 'ownMysql') {
ownMysql = !ownMysql;
}
await post(`/services/${id}/wordpress/settings`, {
ownMysql
});
service.wordpress.ownMysql = ownMysql;
} catch ({ error }) {
return errorNotification(error);
}
}
}
</script>
<div class="flex space-x-1 py-5 font-bold">
<div class="title">Wordpress</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="extraConfig">{$t('forms.extra_config')}</label>
<textarea
bind:value={service.wordpress.extraConfig}
disabled={$status.service.isRunning}
readonly={$status.service.isRunning}
class:resize-none={$status.service.isRunning}
rows="5"
name="extraConfig"
id="extraConfig"
placeholder={!$status.service.isRunning
? `${$t('forms.eg')}:
define('WP_ALLOW_MULTISITE', true);
define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', false);`
: 'N/A'}
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<Setting
bind:setting={service.wordpress.ftpEnabled}
loading={ftpLoading}
disabled={!$status.service.isRunning}
on:click={() => changeSettings('ftpEnabled')}
title="Enable sFTP connection to WordPress data"
description="Enables an on-demand sFTP connection to the WordPress data directory. This is useful if you want to use sFTP to upload files."
/>
</div>
{#if service.wordpress.ftpEnabled}
<div class="grid grid-cols-2 items-center px-10">
<label for="ftpUrl">sFTP Connection URI</label>
<CopyPasswordField id="ftpUrl" readonly disabled name="ftpUrl" value={ftpUrl} />
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="ftpUser">User</label>
<CopyPasswordField id="ftpUser" readonly disabled name="ftpUser" value={ftpUser} />
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="ftpPassword">Password</label>
<CopyPasswordField id="ftpPassword" readonly disabled name="ftpPassword" value={ftpPassword} />
</div>
{/if}
<div class="flex space-x-1 py-5 font-bold">
<div class="title">MySQL</div>
</div>
<div class="grid grid-cols-2 items-center px-10">
<Setting
dataTooltip={$t('forms.must_be_stopped_to_modify')}
bind:setting={service.wordpress.ownMysql}
disabled={$status.service.isRunning}
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}
bind:value={service.wordpress.mysqlHost}
placeholder="{$t('forms.eg')}: db.coolify.io"
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="mysqlPort">Port</label>
<input
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 px-10">
<label for="mysqlDatabase">{$t('index.database')}</label>
<input
name="mysqlDatabase"
id="mysqlDatabase"
required
readonly={readOnly && !service.wordpress.ownMysql}
disabled={readOnly && !service.wordpress.ownMysql}
bind:value={service.wordpress.mysqlDatabase}
placeholder="{$t('forms.eg')}: wordpress_db"
/>
</div>
{#if !service.wordpress.ownMysql}
<div class="grid grid-cols-2 items-center px-10">
<label for="mysqlRootUser">{$t('forms.root_user')}</label>
<input
name="mysqlRootUser"
id="mysqlRootUser"
placeholder="MySQL {$t('forms.root_user')}"
value={service.wordpress.mysqlRootUser}
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="mysqlRootUserPassword">{$t('forms.roots_password')}</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 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>