Merge branch 'next' into grafana-service

This commit is contained in:
Andras Bacsai
2022-09-20 14:50:37 +02:00
committed by GitHub
144 changed files with 4815 additions and 4349 deletions

View File

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

View File

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

View File

@@ -21,163 +21,174 @@
<div class="title">Fider</div>
</div>
<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="space-y-2">
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<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 class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="emailNoreply">Noreply Email</label>
<input
class="w-full"
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>
<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 class="space-y-2">
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<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>
<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 class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="emailMailgunDomain">Mailgun Domain</label>
<input
class="w-full"
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 lg:px-10 px-2">
<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 lg:px-10 px-2 font-bold">
<div class="text-lg">Or</div>
</div>
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="emailSmtpHost">SMTP Host</label>
<input
class="w-full"
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 lg:px-10 px-2">
<label for="emailSmtpPort">SMTP Port</label>
<input
class="w-full"
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 lg:px-10 px-2">
<label for="emailSmtpUser">SMTP User</label>
<input
class="w-full"
name="emailSmtpUser"
id="emailSmtpUser"
readonly={readOnly}
disabled={readOnly}
bind:value={service.fider.emailSmtpUser}
placeholder="{$t('forms.eg')}: user@yourdomain.com"
/>
</div>
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="emailSmtpPassword">SMTP Password</label>
<CopyPasswordField
name="emailSmtpPassword"
id="emailSmtpPassword"
isPasswordField
bind:value={service.fider.emailSmtpPassword}
readonly={readOnly}
disabled={readOnly}
placeholder="{$t('forms.eg')}: s0m3p4ssw0rd"
/>
</div>
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="emailSmtpEnableStartTls">SMTP Start TLS</label>
<input
class="w-full"
name="emailSmtpEnableStartTls"
id="emailSmtpEnableStartTls"
readonly={readOnly}
disabled={readOnly}
bind:value={service.fider.emailSmtpEnableStartTls}
placeholder="{$t('forms.eg')}: true"
/>
</div>
</div>
<div 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 class="space-y-2">
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<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 lg:px-10 px-2">
<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 lg:px-10 px-2">
<label for="postgresqlDatabase">{$t('index.database')}</label>
<CopyPasswordField
name="postgresqlDatabase"
id="postgresqlDatabase"
value={service.fider.postgresqlDatabase}
readonly
disabled
/>
</div>
</div>

View File

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

View File

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

View File

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

View File

@@ -7,7 +7,7 @@
<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">
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="masterKey">{$t('forms.admin_api_key')}</label>
<CopyPasswordField
id="masterKey"

View File

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

View File

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

View File

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

View File

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

View File

@@ -39,6 +39,7 @@
import Weblate from './_Weblate.svelte';
import Explainer from '$lib/components/Explainer.svelte';
import Taiga from './_Taiga.svelte';
import DocLink from '$lib/components/DocLink.svelte';
const { id } = $page.params;
$: isDisabled =
@@ -126,6 +127,20 @@
loading.verification = false;
}
}
async function migrateAppwriteDB() {
loading.verification = true;
try {
await post(`/services/${id}/${service.type}/migrate`, { id: service.id });
return addToast({
message: "Appwrite's database has been migrated.",
type: 'success'
});
} catch (error) {
return errorNotification(error);
} finally {
loading.verification = false;
}
}
async function changeSettings(name: any) {
try {
if (name === 'dualCerts') {
@@ -154,6 +169,9 @@
loading.cleanup = false;
}
}
function doNothing() {
return;
}
onMount(async () => {
if (browser && window.location.hostname === 'demo.coolify.io' && !service.fqdn) {
service.fqdn = `http://${cuid()}.demo.coolify.io`;
@@ -178,68 +196,77 @@
});
</script>
<div class="mx-auto max-w-4xl px-6 pb-12">
<div class="mx-auto max-w-6xl px-6 pb-12">
<form on:submit|preventDefault={handleSubmit} class="py-4">
<div class="flex space-x-1 pb-5">
<div class="title">{$t('general')}</div>
{#if $appSession.isAdmin}
<button
type="submit"
class="btn btn-sm"
class:bg-orange-600={forceSave}
class:hover:bg-orange-400={forceSave}
class:loading={loading.save}
class:bg-services={!loading.save}
disabled={loading.save}
>{loading.save
? $t('forms.save')
: forceSave
? $t('forms.confirm_continue')
: $t('forms.save')}</button
>
{/if}
{#if service.type === 'plausibleanalytics' && $status.service.isRunning}
<button
class="btn btn-sm"
on:click|preventDefault={setEmailsToVerified}
disabled={loading.verification}
class:loading={loading.verification}
>{loading.verification
? $t('forms.verifying')
: $t('forms.verify_emails_without_smtp')}</button
>
<button
class="btn btn-sm"
on:click|preventDefault={cleanupLogs}
disabled={loading.cleanup}
class:loading={loading.cleanup}>Cleanup Unnecessary Database Logs</button
>
{/if}
<div class="flex space-x-1 pb-5 items-center">
<h1 class="title">{$t('general')}</h1>
<div class="flex flex-row space-x-2 items-center">
{#if $appSession.isAdmin}
<button
type="submit"
class="btn btn-sm"
class:bg-orange-600={forceSave}
class:hover:bg-orange-400={forceSave}
class:loading={loading.save}
class:bg-services={!loading.save}
disabled={loading.save}
>{loading.save
? $t('forms.save')
: forceSave
? $t('forms.confirm_continue')
: $t('forms.save')}</button
>
{/if}
{#if service.type === 'plausibleanalytics' && $status.service.isRunning}
<div class="btn-group">
<button
class="btn btn-sm"
on:click|preventDefault={setEmailsToVerified}
disabled={loading.verification}
class:loading={loading.verification}
>{loading.verification
? $t('forms.verifying')
: $t('forms.verify_emails_without_smtp')}</button
>
<button
class="btn btn-sm"
on:click|preventDefault={cleanupLogs}
disabled={loading.cleanup}
class:loading={loading.cleanup}>Cleanup Unnecessary Database Logs</button
>
</div>
{/if}
{#if service.type === 'appwrite' && $status.service.isRunning}
<button
class="btn btn-sm"
on:click|preventDefault={migrateAppwriteDB}
disabled={loading.verification}
class:loading={loading.verification}
>{loading.verification
? 'Migrating... it may take a while...'
: "Migrate Appwrite's Database"}</button
>
<DocLink url="https://appwrite.io/docs/upgrade#run-the-migration" />
{/if}
</div>
</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>
{#if service.type === 'minio' && !service.minio.apiFqdn && $status.service.isRunning}
<div class="py-5">
<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>
<div class="grid grid-cols-2 items-center px-10">
<label for="version" class="text-base font-bold text-stone-100">Version / Tag</label>
{/if}
<div class="grid gap-4 grid-cols-1 grid-rows-1 lg:px-10 px-2">
<div class="mt-2 grid grid-cols-2 items-center">
<label for="name">{$t('forms.name')}</label>
<input name="name" id="name" class="w-full" bind:value={service.name} required />
</div>
<div class="grid grid-cols-2 items-center">
<label for="version">Version / Tag</label>
<a
href={$appSession.isAdmin && !$status.service.isRunning && !$status.service.initialLoading
? `/services/${id}/configuration/version?from=/services/${id}`
@@ -247,6 +274,7 @@
class="no-underline"
>
<input
class="w-full"
value={service.version}
id="service"
readonly
@@ -255,10 +283,8 @@
/></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 class="grid grid-cols-2 items-center">
<label for="destination">{$t('application.destination')}</label>
<div>
{#if service.destinationDockerId}
<div class="no-underline">
@@ -266,17 +292,16 @@
value={service.destinationDocker.name}
id="destination"
disabled
class="bg-transparent "
class="bg-transparent w-full"
/>
</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>
<div class="grid grid-cols-2 items-center">
<label for="fqdn">Console URL</label>
<CopyPasswordField
placeholder="eg: https://console.min.io"
@@ -289,13 +314,10 @@
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 <Explainer explanation={$t('application.https_explainer')} /></label
>
</div>
<div class="grid grid-cols-2 items-center">
<label for="apiFqdn"
>API URL <Explainer explanation={$t('application.https_explainer')} /></label
>
<CopyPasswordField
placeholder="eg: https://min.io"
readonly={!$appSession.isAdmin && !$status.service.isRunning}
@@ -308,14 +330,11 @@
/>
</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')}
<Explainer explanation={$t('application.https_explainer')} />
</label>
</div>
<div class="grid grid-cols-2 items-center">
<label for="fqdn"
>{$t('application.url_fqdn')}
<Explainer explanation={$t('application.https_explainer')} />
</label>
<CopyPasswordField
placeholder="eg: https://analytics.coollabs.io"
readonly={!$appSession.isAdmin && !$status.service.isRunning}
@@ -330,56 +349,49 @@
/>
</div>
{/if}
{#if forceSave}
<div class="flex-col space-y-2 pt-4 text-center">
{#if isNonWWWDomainOK}
</div>
{#if forceSave}
<div class="flex-col space-y-2 pt-4 text-center">
{#if isNonWWWDomainOK}
<button
class="btn btn-sm bg-green-600 hover:bg-green-500"
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)}
>DNS settings for {nonWWWDomain} is OK, click to recheck.</button
>
{:else}
<button
class="btn btn-sm bg-red-600 hover:bg-red-500"
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)}
>DNS settings for {nonWWWDomain} is invalid, click to recheck.</button
>
{/if}
{#if dualCerts}
{#if isWWWDomainOK}
<button
class="btn btn-sm bg-green-600 hover:bg-green-500"
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)}
>DNS settings for {nonWWWDomain} is OK, click to recheck.</button
on:click|preventDefault={() => isDNSValid(getDomain(`www.${nonWWWDomain}`), true)}
>DNS settings for www.{nonWWWDomain} is OK, click to recheck.</button
>
{:else}
<button
class="btn btn-sm bg-red-600 hover:bg-red-500"
on:click|preventDefault={() => isDNSValid(getDomain(nonWWWDomain), false)}
>DNS settings for {nonWWWDomain} is invalid, click to recheck.</button
on:click|preventDefault={() => isDNSValid(getDomain(`www.${nonWWWDomain}`), true)}
>DNS settings for www.{nonWWWDomain} is invalid, click to recheck.</button
>
{/if}
{#if dualCerts}
{#if isWWWDomainOK}
<button
class="btn btn-sm bg-green-600 hover:bg-green-500"
on:click|preventDefault={() => isDNSValid(getDomain(`www.${nonWWWDomain}`), true)}
>DNS settings for www.{nonWWWDomain} is OK, click to recheck.</button
>
{:else}
<button
class="btn btn-sm bg-red-600 hover:bg-red-500"
on:click|preventDefault={() => isDNSValid(getDomain(`www.${nonWWWDomain}`), true)}
>DNS settings for www.{nonWWWDomain} is invalid, click to recheck.</button
>
{/if}
{/if}
</div>
{/if}
<div class="grid grid-cols-2 items-center px-10">
<Setting
id="dualCerts"
disabled={$status.service.isRunning}
dataTooltip={$t('forms.must_be_stopped_to_modify')}
bind:setting={dualCerts}
title={$t('application.ssl_www_and_non_www')}
description={$t('services.generate_www_non_www_ssl')}
on:click={() => !$status.service.isRunning && changeSettings('dualCerts')}
/>
{/if}
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="exposePort" class="text-base font-bold text-stone-100"
{/if}
<div class="grid grid-flow-row gap-2 lg:px-10 px-2 pt-4">
<div class="grid grid-cols-2 items-center">
<label for="exposePort"
>Exposed Port <Explainer
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
class="w-full"
readonly={!$appSession.isAdmin && !$status.service.isRunning}
disabled={!$appSession.isAdmin ||
$status.service.isRunning ||
@@ -390,38 +402,48 @@
placeholder="12345"
/>
</div>
{#if service.type === 'plausibleanalytics'}
<PlausibleAnalytics bind:service {readOnly} />
{:else if service.type === 'minio'}
<MinIo {service} />
{:else if service.type === 'vscodeserver'}
<VsCodeServer {service} />
{:else if service.type === 'wordpress'}
<Wordpress bind:service {readOnly} {settings} />
{:else if service.type === 'ghost'}
<Ghost bind:service {readOnly} />
{:else if service.type === 'meilisearch'}
<MeiliSearch bind:service />
{:else if service.type === 'umami'}
<Umami bind:service />
{:else if service.type === 'hasura'}
<Hasura bind:service />
{:else if service.type === 'fider'}
<Fider bind:service {readOnly} />
{:else if service.type === 'appwrite'}
<Appwrite bind:service {readOnly} />
{:else if service.type === 'moodle'}
<Moodle bind:service {readOnly} />
{:else if service.type === 'glitchTip'}
<GlitchTip bind:service />
{:else if service.type === 'searxng'}
<Searxng bind:service />
{:else if service.type === 'weblate'}
<Weblate bind:service />
{:else if service.type === 'taiga'}
<Taiga bind:service />
{/if}
<div class="grid grid-cols-2 items-center">
<Setting
id="dualCerts"
disabled={$status.service.isRunning}
dataTooltip={$t('forms.must_be_stopped_to_modify')}
bind:setting={dualCerts}
title={$t('application.ssl_www_and_non_www')}
description={$t('services.generate_www_non_www_ssl')}
on:click={() => !$status.service.isRunning && changeSettings('dualCerts')}
/>
</div>
</div>
{#if service.type === 'plausibleanalytics'}
<PlausibleAnalytics bind:service {readOnly} />
{:else if service.type === 'minio'}
<MinIo {service} />
{:else if service.type === 'vscodeserver'}
<VsCodeServer {service} />
{:else if service.type === 'wordpress'}
<Wordpress bind:service {readOnly} {settings} />
{:else if service.type === 'ghost'}
<Ghost bind:service {readOnly} />
{:else if service.type === 'meilisearch'}
<MeiliSearch bind:service />
{:else if service.type === 'umami'}
<Umami bind:service />
{:else if service.type === 'hasura'}
<Hasura bind:service />
{:else if service.type === 'fider'}
<Fider bind:service {readOnly} />
{:else if service.type === 'appwrite'}
<Appwrite bind:service {readOnly} />
{:else if service.type === 'moodle'}
<Moodle bind:service {readOnly} />
{:else if service.type === 'glitchTip'}
<GlitchTip bind:service />
{:else if service.type === 'searxng'}
<Searxng bind:service />
{:else if service.type === 'weblate'}
<Weblate bind:service />
{:else if service.type === 'taiga'}
<Taiga bind:service />
{/if}
</form>
</div>

View File

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

View File

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

View File

@@ -8,7 +8,7 @@
<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">
<div class="grid grid-cols-2 items-center lg:px-10 px-2">
<label for="password">{$t('forms.password')}</label>
<CopyPasswordField
id="password"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -50,17 +50,7 @@
});
</script>
<div class="flex h-20 items-center space-x-2 p-5 px-6 font-bold">
<div class="-mb-5 flex-col">
<div class="md:max-w-64 truncate text-base tracking-tight md:text-2xl lg:block">
Configuration
</div>
<span class="text-xs">{service.name}</span>
</div>
<ServiceLinks {service} />
</div>
<div class="mx-auto max-w-4xl px-6 py-4">
<div class="text-2xl font-bold">Service Usage</div>
<div class="mx-auto max-w-6xl px-6 lg:my-0 my-4 lg:pt-0 pt-4 rounded">
<div class="text-center">
<div class="stat w-64">
<div class="stat-title">Used Memory / Memory Limit</div>

View File

@@ -128,7 +128,7 @@
<button
id="follow"
on:click={followBuild}
class="bg-transparent btn btn-sm"
class="bg-transparent btn btn-sm btn-link"
class:text-green-500={followingLogs}
>
<svg
@@ -150,16 +150,10 @@
</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"
bind:this={logsEl}
on:scroll={detect}
>
<div class="px-2 pr-14">
{#each logs as log}
{log + '\n'}
{/each}
</div>
<div class="font-mono w-full rounder bg-coolgray-200 p-5 overflow-x-auto overflox-y-auto max-h-[80vh] rounded-md mb-20 flex flex-col whitespace-nowrap -mt-12 scrollbar-thumb-coollabs scrollbar-track-coolgray-200 scrollbar-w-1">
{#each logs as log}
<p>{log.line + '\n'}</p>
{/each}
</div>
</div>
{/if}

View File

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