fix: UI + refactor
This commit is contained in:
parent
290dbc43cb
commit
44a691ae29
@ -45,7 +45,7 @@ export function getAPIUrl() {
|
||||
if (process.env.CODESANDBOX_HOST) {
|
||||
return `https://${process.env.CODESANDBOX_HOST.replace(/\$PORT/, '3001')}`
|
||||
}
|
||||
return isDev ? 'http://host.docker.internal:3001' : 'http://localhost:3000';
|
||||
return isDev ? 'http://localhost:3001' : 'http://localhost:3000';
|
||||
}
|
||||
|
||||
export function getUIUrl() {
|
||||
|
@ -452,12 +452,14 @@ export async function stopApplication(request: FastifyRequest<OnlyId>, reply: Fa
|
||||
export async function deleteApplication(request: FastifyRequest<DeleteApplication>, reply: FastifyReply) {
|
||||
try {
|
||||
const { id } = request.params
|
||||
const { force } = request.body
|
||||
|
||||
const { teamId } = request.user
|
||||
const application = await prisma.application.findUnique({
|
||||
where: { id },
|
||||
include: { destinationDocker: true }
|
||||
});
|
||||
if (application?.destinationDockerId && application.destinationDocker?.network) {
|
||||
if (!force && application?.destinationDockerId && application.destinationDocker?.network) {
|
||||
const { stdout: containers } = await executeDockerCmd({
|
||||
dockerId: application.destinationDocker.id,
|
||||
command: `docker ps -a --filter network=${application.destinationDocker.network} --filter name=${id} --format '{{json .}}'`
|
||||
|
@ -29,6 +29,7 @@ export interface SaveApplicationSettings extends OnlyId {
|
||||
}
|
||||
export interface DeleteApplication extends OnlyId {
|
||||
Querystring: { domain: string; };
|
||||
Body: { force: boolean }
|
||||
}
|
||||
export interface CheckDomain extends OnlyId {
|
||||
Querystring: { domain: string; };
|
||||
|
@ -7,7 +7,7 @@ import { ComposeFile, createDirectories, decrypt, encrypt, errorHandler, execute
|
||||
import { day } from '../../../../lib/dayjs';
|
||||
|
||||
import { GetDatabaseLogs, OnlyId, SaveDatabase, SaveDatabaseDestination, SaveDatabaseSettings, SaveVersion } from '../../../../types';
|
||||
import { SaveDatabaseType } from './types';
|
||||
import { DeleteDatabase, SaveDatabaseType } from './types';
|
||||
|
||||
export async function listDatabases(request: FastifyRequest) {
|
||||
try {
|
||||
@ -167,6 +167,7 @@ export async function saveDatabaseDestination(request: FastifyRequest<SaveDataba
|
||||
const { id } = request.params;
|
||||
const { destinationId } = request.body;
|
||||
|
||||
const { arch } = await listSettings();
|
||||
await prisma.database.update({
|
||||
where: { id },
|
||||
data: { destinationDocker: { connect: { id: destinationId } } }
|
||||
@ -181,7 +182,7 @@ export async function saveDatabaseDestination(request: FastifyRequest<SaveDataba
|
||||
|
||||
if (destinationDockerId) {
|
||||
if (type && version) {
|
||||
const baseImage = getDatabaseImage(type);
|
||||
const baseImage = getDatabaseImage(type, arch);
|
||||
executeDockerCmd({ dockerId, command: `docker pull ${baseImage}:${version}` })
|
||||
}
|
||||
}
|
||||
@ -360,19 +361,22 @@ export async function getDatabaseLogs(request: FastifyRequest<GetDatabaseLogs>)
|
||||
return errorHandler({ status, message })
|
||||
}
|
||||
}
|
||||
export async function deleteDatabase(request: FastifyRequest<OnlyId>) {
|
||||
export async function deleteDatabase(request: FastifyRequest<DeleteDatabase>) {
|
||||
try {
|
||||
const teamId = request.user.teamId;
|
||||
const { id } = request.params;
|
||||
const { force } = request.body;
|
||||
const database = await prisma.database.findFirst({
|
||||
where: { id, teams: { some: { id: teamId === '0' ? undefined : teamId } } },
|
||||
include: { destinationDocker: true, settings: true }
|
||||
});
|
||||
if (database.dbUserPassword) database.dbUserPassword = decrypt(database.dbUserPassword);
|
||||
if (database.rootUserPassword) database.rootUserPassword = decrypt(database.rootUserPassword);
|
||||
if (database.destinationDockerId) {
|
||||
const everStarted = await stopDatabaseContainer(database);
|
||||
if (everStarted) await stopTcpHttpProxy(id, database.destinationDocker, database.publicPort);
|
||||
if (!force) {
|
||||
if (database.dbUserPassword) database.dbUserPassword = decrypt(database.dbUserPassword);
|
||||
if (database.rootUserPassword) database.rootUserPassword = decrypt(database.rootUserPassword);
|
||||
if (database.destinationDockerId) {
|
||||
const everStarted = await stopDatabaseContainer(database);
|
||||
if (everStarted) await stopTcpHttpProxy(id, database.destinationDocker, database.publicPort);
|
||||
}
|
||||
}
|
||||
await prisma.databaseSettings.deleteMany({ where: { databaseId: id } });
|
||||
await prisma.database.delete({ where: { id } });
|
||||
@ -436,7 +440,7 @@ export async function saveDatabaseSettings(request: FastifyRequest<SaveDatabaseS
|
||||
let publicPort = null
|
||||
|
||||
const { destinationDocker: { id: dockerId } } = await prisma.database.findUnique({ where: { id }, include: { destinationDocker: true } })
|
||||
|
||||
|
||||
if (isPublic) {
|
||||
publicPort = await getFreePublicPort(id, dockerId);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { FastifyPluginAsync } from 'fastify';
|
||||
import { deleteDatabase, getDatabase, getDatabaseLogs, getDatabaseStatus, getDatabaseTypes, getDatabaseUsage, getVersions, listDatabases, newDatabase, saveDatabase, saveDatabaseDestination, saveDatabaseSettings, saveDatabaseType, saveVersion, startDatabase, stopDatabase } from './handlers';
|
||||
|
||||
import type { GetDatabaseLogs, OnlyId, SaveDatabase, SaveDatabaseDestination, SaveDatabaseSettings, SaveVersion } from '../../../../types';
|
||||
import type { DeleteDatabase, GetDatabaseLogs, OnlyId, SaveDatabase, SaveDatabaseDestination, SaveDatabaseSettings, SaveVersion } from '../../../../types';
|
||||
import type { SaveDatabaseType } from './types';
|
||||
|
||||
const root: FastifyPluginAsync = async (fastify): Promise<void> => {
|
||||
@ -13,7 +13,7 @@ const root: FastifyPluginAsync = async (fastify): Promise<void> => {
|
||||
|
||||
fastify.get<OnlyId>('/:id', async (request) => await getDatabase(request));
|
||||
fastify.post<SaveDatabase>('/:id', async (request, reply) => await saveDatabase(request, reply));
|
||||
fastify.delete<OnlyId>('/:id', async (request) => await deleteDatabase(request));
|
||||
fastify.delete<DeleteDatabase>('/:id', async (request) => await deleteDatabase(request));
|
||||
|
||||
fastify.get<OnlyId>('/:id/status', async (request) => await getDatabaseStatus(request));
|
||||
|
||||
|
@ -2,4 +2,7 @@ import type { OnlyId } from "../../../../types";
|
||||
|
||||
export interface SaveDatabaseType extends OnlyId {
|
||||
Body: { type: string }
|
||||
}
|
||||
export interface DeleteDatabase extends OnlyId {
|
||||
Body: { force: string }
|
||||
}
|
@ -96,5 +96,3 @@ export interface SetGlitchTipSettings extends OnlyId {
|
||||
emailSmtpUseTls: boolean
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,4 +36,3 @@ export interface SaveDatabaseSettings extends OnlyId {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -65,6 +65,7 @@
|
||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||
|
||||
let statusInterval: any;
|
||||
let forceDelete = false;
|
||||
$disabledButton =
|
||||
!$appSession.isAdmin ||
|
||||
(!application.fqdn && !application.settings.isBot) ||
|
||||
@ -97,14 +98,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteApplication(name: string) {
|
||||
async function deleteApplication(name: string, force: boolean) {
|
||||
const sure = confirm($t('application.confirm_to_delete', { name }));
|
||||
if (sure) {
|
||||
$status.application.initialLoading = true;
|
||||
try {
|
||||
await del(`/applications/${id}`, { id });
|
||||
await del(`/applications/${id}`, { id, force });
|
||||
return await goto(`/applications`);
|
||||
} catch (error) {
|
||||
if (error.message.startsWith(`Command failed: SSH_AUTH_SOCK=/tmp/ssh-agent.pid`)) {
|
||||
forceDelete = true;
|
||||
}
|
||||
return errorNotification(error);
|
||||
} finally {
|
||||
$status.application.initialLoading = false;
|
||||
@ -117,9 +121,9 @@
|
||||
$status.application.loading = true;
|
||||
await post(`/applications/${id}/restart`, {});
|
||||
addToast({
|
||||
type: 'success',
|
||||
message: 'Restart successful.'
|
||||
});
|
||||
type: 'success',
|
||||
message: 'Restart successful.'
|
||||
});
|
||||
} catch (error) {
|
||||
return errorNotification(error);
|
||||
} finally {
|
||||
@ -537,16 +541,29 @@
|
||||
>
|
||||
<div class="border border-coolgray-500 h-8" />
|
||||
|
||||
<button
|
||||
id="delete"
|
||||
on:click={() => deleteApplication(application.name)}
|
||||
type="submit"
|
||||
disabled={!$appSession.isAdmin}
|
||||
class:hover:text-red-500={$appSession.isAdmin}
|
||||
class="icons bg-transparent text-sm"
|
||||
>
|
||||
<DeleteIcon />
|
||||
</button>
|
||||
{#if forceDelete}
|
||||
<button
|
||||
on:click={() => deleteApplication(application.name, true)}
|
||||
type="submit"
|
||||
disabled={!$appSession.isAdmin}
|
||||
class:bg-red-600={$appSession.isAdmin}
|
||||
class:hover:bg-red-500={$appSession.isAdmin}
|
||||
class="icons bg-transparent text-sm"
|
||||
>
|
||||
Force Delete
|
||||
</button>
|
||||
{:else}
|
||||
<button
|
||||
id="delete"
|
||||
on:click={() => deleteApplication(application.name, false)}
|
||||
type="submit"
|
||||
disabled={!$appSession.isAdmin}
|
||||
class:hover:text-red-500={$appSession.isAdmin}
|
||||
class="icons bg-transparent text-sm"
|
||||
>
|
||||
<DeleteIcon />
|
||||
</button>
|
||||
{/if}
|
||||
</nav>
|
||||
<slot />
|
||||
|
||||
|
@ -169,10 +169,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
function selectBranch(event: any) {
|
||||
selected.branch = event.detail;
|
||||
isBranchAlreadyUsed();
|
||||
}
|
||||
async function loadBranches(page: number = 1) {
|
||||
let perPage = 100;
|
||||
//@ts-ignore
|
||||
@ -199,21 +195,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function isBranchAlreadyUsed() {
|
||||
async function isBranchAlreadyUsed(event) {
|
||||
selected.branch = event.detail;
|
||||
try {
|
||||
const data = await get(
|
||||
`/applications/${id}/configuration/repository?repository=${selected.project.path_with_namespace}&branch=${selected.branch.name}`
|
||||
);
|
||||
if (data.used) {
|
||||
const sure = confirm($t('application.configuration.branch_already_in_use'));
|
||||
if (sure) {
|
||||
autodeploy = false;
|
||||
showSave = true;
|
||||
return true;
|
||||
}
|
||||
showSave = false;
|
||||
return true;
|
||||
}
|
||||
// const data = await get(
|
||||
// `/applications/${id}/configuration/repository?repository=${selected.project.path_with_namespace}&branch=${selected.branch.name}`
|
||||
// );
|
||||
// if (data.used) {
|
||||
// const sure = confirm($t('application.configuration.branch_already_in_use'));
|
||||
// if (sure) {
|
||||
// autodeploy = false;
|
||||
// showSave = true;
|
||||
// return true;
|
||||
// }
|
||||
// showSave = false;
|
||||
// return true;
|
||||
// }
|
||||
showSave = true;
|
||||
} catch (error) {
|
||||
return errorNotification(error);
|
||||
@ -227,9 +224,7 @@
|
||||
}
|
||||
}
|
||||
async function setWebhook(url: any, webhookToken: any) {
|
||||
const host = dev
|
||||
? getWebhookUrl('gitlab')
|
||||
: `${window.location.origin}/webhooks/gitlab/events`;
|
||||
const host = dev ? getWebhookUrl('gitlab') : `${window.location.origin}/webhooks/gitlab/events`;
|
||||
try {
|
||||
await post(
|
||||
url,
|
||||
@ -294,17 +289,15 @@
|
||||
);
|
||||
await post(updateDeployKeyIdUrl, { deployKeyId: id });
|
||||
} catch (error) {
|
||||
return errorNotification(error);
|
||||
} finally {
|
||||
loading.save = false;
|
||||
return errorNotification(error);
|
||||
}
|
||||
|
||||
try {
|
||||
await setWebhook(webhookUrl, webhookToken);
|
||||
} catch (error) {
|
||||
return errorNotification(error);
|
||||
} finally {
|
||||
loading.save = false;
|
||||
return errorNotification(error);
|
||||
}
|
||||
|
||||
const url = `/applications/${id}/configuration/repository`;
|
||||
@ -317,11 +310,11 @@
|
||||
autodeploy,
|
||||
webhookToken
|
||||
});
|
||||
loading.save = false;
|
||||
return await goto(from || `/applications/${id}/configuration/buildpack`);
|
||||
} catch (error) {
|
||||
return errorNotification(error);
|
||||
} finally {
|
||||
loading.save = false;
|
||||
return errorNotification(error);
|
||||
}
|
||||
}
|
||||
async function handleSubmit() {
|
||||
@ -396,7 +389,7 @@
|
||||
showIndicator={!loading.branches}
|
||||
isWaiting={loading.branches}
|
||||
isDisabled={loading.branches || !selected.project}
|
||||
on:select={selectBranch}
|
||||
on:select={isBranchAlreadyUsed}
|
||||
on:clear={() => {
|
||||
showSave = false;
|
||||
selected.branch = null;
|
||||
@ -425,7 +418,7 @@
|
||||
configuration <a href={`/sources/${application.gitSource.id}`}>here.</a>
|
||||
</div>
|
||||
<button
|
||||
class="w-40 bg-green-600"
|
||||
class="btn btn-sm w-40 bg-green-600"
|
||||
on:click|stopPropagation|preventDefault={() => window.location.reload()}
|
||||
>
|
||||
Try again
|
||||
|
@ -4,7 +4,6 @@
|
||||
import { page } from '$app/stores';
|
||||
|
||||
import Select from 'svelte-select';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { errorNotification } from '$lib/common';
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
import { errorNotification } from '$lib/common';
|
||||
import { appSession } from '$lib/store';
|
||||
import PublicRepository from './_PublicRepository.svelte';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
|
||||
const { id } = $page.params;
|
||||
|
@ -526,7 +526,7 @@
|
||||
disabled={$status.application.isRunning}
|
||||
/>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center pb-8">
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<Setting
|
||||
id="dualCerts"
|
||||
dataTooltip={$t('forms.must_be_stopped_to_modify')}
|
||||
@ -539,15 +539,13 @@
|
||||
/>
|
||||
</div>
|
||||
{#if !isBot}
|
||||
<div class="grid grid-cols-2">
|
||||
<div class="flex-col">
|
||||
<label for="fqdn" class="pt-2 text-base font-bold text-stone-100"
|
||||
>{$t('application.url_fqdn')}
|
||||
<DocLink
|
||||
explanation={"If you specify <span class='text-settings font-bold'>https</span>, the application will be accessible only over https.<br>SSL certificate will be generated automatically.<br><br>If you specify <span class='text-settings font-bold'>www</span>, the application will be redirected (302) from non-www and vice versa.<br><br>To modify the domain, you must first stop the application.<br><br><span class='text-settings font-bold'>You must set your DNS to point to the server IP in advance.</span>"}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="fqdn" class="text-base font-bold text-stone-100"
|
||||
>{$t('application.url_fqdn')}
|
||||
<DocLink
|
||||
explanation={"If you specify <span class='text-settings font-bold'>https</span>, the application will be accessible only over https.<br>SSL certificate will be generated automatically.<br><br>If you specify <span class='text-settings font-bold'>www</span>, the application will be redirected (302) from non-www and vice versa.<br><br>To modify the domain, you must first stop the application.<br><br><span class='text-settings font-bold'>You must set your DNS to point to the server IP in advance.</span>"}
|
||||
/>
|
||||
</label>
|
||||
<div>
|
||||
<input
|
||||
readonly={isDisabled}
|
||||
@ -648,7 +646,10 @@
|
||||
{/if}
|
||||
{#if !staticDeployments.includes(application.buildPack)}
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="port" class="text-base font-bold text-stone-100">{$t('forms.port')}</label>
|
||||
<label for="port" class="text-base font-bold text-stone-100"
|
||||
>{$t('forms.port')}
|
||||
<DocLink explanation={'The port your application listens on.'} /></label
|
||||
>
|
||||
<input
|
||||
disabled={isDisabled}
|
||||
readonly={!$appSession.isAdmin}
|
||||
@ -657,7 +658,6 @@
|
||||
bind:value={application.port}
|
||||
placeholder="{$t('forms.default')}: 'python' ? '8000' : '3000'"
|
||||
/>
|
||||
<Explainer text={'The port your application listens on.'} />
|
||||
</div>
|
||||
{/if}
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
@ -676,7 +676,7 @@
|
||||
/>
|
||||
</div>
|
||||
{#if !notNodeDeployments.includes(application.buildPack)}
|
||||
<div class="grid grid-cols-2 items-center pt-4">
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="installCommand" class="text-base font-bold text-stone-100"
|
||||
>{$t('application.install_command')}</label
|
||||
>
|
||||
|
@ -87,7 +87,9 @@
|
||||
</div>
|
||||
|
||||
<div class="mx-auto max-w-6xl rounded-xl px-6 pt-4">
|
||||
|
||||
<div class="flex justify-center py-4 text-center">
|
||||
<Explainer customClass="w-full" text={$t('application.storage.persistent_storage_explainer')} />
|
||||
</div>
|
||||
<table class="mx-auto border-separate text-left">
|
||||
<thead>
|
||||
<tr class="h-12">
|
||||
@ -107,7 +109,4 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="flex justify-center py-4 text-center">
|
||||
<Explainer customClass="w-full" text={$t('application.storage.persistent_storage_explainer')} />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -16,7 +16,7 @@
|
||||
import { t } from '$lib/translations';
|
||||
import { errorNotification } from '$lib/common';
|
||||
import { addToast, appSession, status } from '$lib/store';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
|
||||
const { id } = $page.params;
|
||||
|
||||
@ -209,13 +209,13 @@
|
||||
<div class="grid grid-cols-2 items-center px-10 pb-8">
|
||||
<div>
|
||||
<label for="url" class="text-base font-bold text-stone-100"
|
||||
>{$t('database.connection_string')}</label
|
||||
>{$t('database.connection_string')}
|
||||
{#if !isPublic && database.destinationDocker.remoteEngine}
|
||||
<DocLink
|
||||
explanation="You can only access the database with this URL if your application is deployed to the same Destination."
|
||||
/>
|
||||
{/if}</label
|
||||
>
|
||||
{#if !isPublic && database.destinationDocker.remoteEngine}
|
||||
<Explainer
|
||||
text="You can only access the database with this URL if your application is deployed to the same Destination."
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
<CopyPasswordField
|
||||
textarea={true}
|
||||
|
@ -2,8 +2,8 @@
|
||||
export let database: any;
|
||||
import { status } from '$lib/store';
|
||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import { t } from '$lib/translations';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 py-5 font-bold">
|
||||
@ -37,7 +37,8 @@
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="dbUserPassword" class="text-base font-bold text-stone-100"
|
||||
>{$t('forms.password')}</label
|
||||
>{$t('forms.password')}
|
||||
<DocLink explanation="Could be changed while the database is running." /></label
|
||||
>
|
||||
<CopyPasswordField
|
||||
disabled={!$status.database.isRunning}
|
||||
@ -48,7 +49,6 @@
|
||||
name="dbUserPassword"
|
||||
bind:value={database.dbUserPassword}
|
||||
/>
|
||||
<Explainer text="Could be changed while the database is running." />
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="rootUser" class="text-base font-bold text-stone-100">{$t('forms.root_user')}</label>
|
||||
@ -63,7 +63,7 @@
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="rootUserPassword" class="text-base font-bold text-stone-100"
|
||||
>{$t('forms.roots_password')}</label
|
||||
>{$t('forms.roots_password')} <DocLink explanation="Could be changed while the database is running." /></label
|
||||
>
|
||||
<CopyPasswordField
|
||||
disabled={!$status.database.isRunning}
|
||||
@ -74,6 +74,5 @@
|
||||
name="rootUserPassword"
|
||||
bind:value={database.rootUserPassword}
|
||||
/>
|
||||
<Explainer text="Could be changed while the database is running." />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,8 +2,8 @@
|
||||
export let database: any;
|
||||
import { status } from '$lib/store';
|
||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import { t } from '$lib/translations';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 py-5 font-bold">
|
||||
@ -23,7 +23,8 @@
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="rootUserPassword" class="text-base font-bold text-stone-100"
|
||||
>{$t('forms.roots_password')}</label
|
||||
>{$t('forms.roots_password')}
|
||||
<DocLink explanation="Could be changed while the database is running." /></label
|
||||
>
|
||||
<CopyPasswordField
|
||||
disabled={!$status.database.isRunning}
|
||||
@ -34,6 +35,5 @@
|
||||
name="rootUserPassword"
|
||||
bind:value={database.rootUserPassword}
|
||||
/>
|
||||
<Explainer text="Could be changed while the database is running." />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,6 +4,7 @@
|
||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import { t } from '$lib/translations';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 py-5 font-bold">
|
||||
@ -37,7 +38,7 @@
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="dbUserPassword" class="text-base font-bold text-stone-100"
|
||||
>{$t('forms.password')}</label
|
||||
>{$t('forms.password')} <DocLink explanation="Could be changed while the database is running." /></label
|
||||
>
|
||||
<CopyPasswordField
|
||||
disabled={!$status.database.isRunning}
|
||||
@ -48,7 +49,6 @@
|
||||
name="dbUserPassword"
|
||||
bind:value={database.dbUserPassword}
|
||||
/>
|
||||
<Explainer text="Could be changed while the database is running." />
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="rootUser" class="text-base font-bold text-stone-100">{$t('forms.root_user')}</label>
|
||||
@ -63,7 +63,7 @@
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="rootUserPassword" class="text-base font-bold text-stone-100"
|
||||
>{$t('forms.roots_password')}</label
|
||||
>{$t('forms.roots_password')} <DocLink explanation="Could be changed while the database is running." /></label
|
||||
>
|
||||
<CopyPasswordField
|
||||
disabled={!$status.database.isRunning}
|
||||
@ -74,6 +74,5 @@
|
||||
name="rootUserPassword"
|
||||
bind:value={database.rootUserPassword}
|
||||
/>
|
||||
<Explainer text="Could be changed while the database is running." />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,8 +2,8 @@
|
||||
export let database: any;
|
||||
import { status } from '$lib/store';
|
||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import { t } from '$lib/translations';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 py-5 font-bold">
|
||||
@ -26,7 +26,9 @@
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="rootUser" class="text-base font-bold text-stone-100"
|
||||
>Root (postgres) User Password</label
|
||||
>Postgres User Password <DocLink
|
||||
explanation="Could be changed while the database is running."
|
||||
/></label
|
||||
>
|
||||
<CopyPasswordField
|
||||
disabled={!$status.database.isRunning}
|
||||
@ -37,7 +39,6 @@
|
||||
name="rootUserPassword"
|
||||
bind:value={database.rootUserPassword}
|
||||
/>
|
||||
<Explainer text="Could be changed while the database is running." />
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="dbUser" class="text-base font-bold text-stone-100">{$t('forms.user')}</label>
|
||||
@ -52,7 +53,8 @@
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="dbUserPassword" class="text-base font-bold text-stone-100"
|
||||
>{$t('forms.password')}</label
|
||||
>{$t('forms.password')}
|
||||
<DocLink explanation="Could be changed while the database is running." /></label
|
||||
>
|
||||
<CopyPasswordField
|
||||
disabled={!$status.database.isRunning}
|
||||
@ -63,6 +65,5 @@
|
||||
name="dbUserPassword"
|
||||
bind:value={database.dbUserPassword}
|
||||
/>
|
||||
<Explainer text="Could be changed while the database is running." />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,8 +2,8 @@
|
||||
export let database: any;
|
||||
import { status } from '$lib/store';
|
||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import { t } from '$lib/translations';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 py-5 font-bold">
|
||||
@ -12,7 +12,8 @@
|
||||
<div class="space-y-2 px-10">
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="dbUserPassword" class="text-base font-bold text-stone-100"
|
||||
>{$t('forms.password')}</label
|
||||
>{$t('forms.password')}
|
||||
<DocLink explanation="Could be changed while the database is running." /></label
|
||||
>
|
||||
<CopyPasswordField
|
||||
disabled={!$status.database.isRunning}
|
||||
@ -23,6 +24,5 @@
|
||||
name="dbUserPassword"
|
||||
bind:value={database.dbUserPassword}
|
||||
/>
|
||||
<Explainer text="Could be changed while the database is running." />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -65,15 +65,16 @@
|
||||
const { id } = $page.params;
|
||||
|
||||
let statusInterval: any = false;
|
||||
let forceDelete = false;
|
||||
|
||||
$disabledButton = !$appSession.isAdmin;
|
||||
|
||||
async function deleteDatabase() {
|
||||
async function deleteDatabase(force: boolean) {
|
||||
const sure = confirm(`Are you sure you would like to delete '${database.name}'?`);
|
||||
if (sure) {
|
||||
$status.database.initialLoading = true;
|
||||
try {
|
||||
await del(`/databases/${database.id}`, { id: database.id });
|
||||
await del(`/databases/${database.id}`, { id: database.id, force });
|
||||
return await goto('/databases');
|
||||
} catch (error) {
|
||||
return errorNotification(error);
|
||||
@ -304,14 +305,26 @@
|
||||
></a
|
||||
>
|
||||
<Tooltip triggeredBy="#databaselogs">{'Logs'}</Tooltip>
|
||||
<button
|
||||
id="delete"
|
||||
on:click={deleteDatabase}
|
||||
type="submit"
|
||||
disabled={!$appSession.isAdmin}
|
||||
class:hover:text-red-500={$appSession.isAdmin}
|
||||
class="icons bg-transparent text-sm"><DeleteIcon /></button
|
||||
>
|
||||
{#if forceDelete}
|
||||
<button
|
||||
on:click={() => deleteDatabase(true)}
|
||||
type="submit"
|
||||
disabled={!$appSession.isAdmin}
|
||||
class:hover:text-red-500={$appSession.isAdmin}
|
||||
class="icons bg-transparent text-sm"
|
||||
>
|
||||
Force Delete</button
|
||||
>{:else}
|
||||
<button
|
||||
id="delete"
|
||||
on:click={() => deleteDatabase(false)}
|
||||
type="submit"
|
||||
disabled={!$appSession.isAdmin}
|
||||
class:hover:text-red-500={$appSession.isAdmin}
|
||||
class="icons bg-transparent text-sm"><DeleteIcon /></button
|
||||
>
|
||||
{/if}
|
||||
|
||||
<Tooltip triggeredBy="#delete">{'Delete'}</Tooltip>
|
||||
</nav>
|
||||
{/if}
|
||||
|
@ -1,14 +1,15 @@
|
||||
<script lang="ts">
|
||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
import { t } from '$lib/translations';
|
||||
export let readOnly: any;
|
||||
export let service: any;
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 py-5">
|
||||
<div class="title">Ghost</div>
|
||||
<Explainer text={'You can change these values in the Ghost admin panel.'} />
|
||||
<div class="title">
|
||||
Ghost <DocLink explanation="You can change these values in the Ghost admin panel." />
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center px-10">
|
||||
<label for="email">{$t('forms.default_email_address')}</label>
|
||||
|
@ -1,6 +1,5 @@
|
||||
<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>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
import { appSession, status } from '$lib/store';
|
||||
import { t } from '$lib/translations';
|
||||
export let service: any;
|
||||
@ -11,7 +11,11 @@
|
||||
<div class="title">Plausible Analytics</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center px-10">
|
||||
<label for="scriptName">Script Name</label>
|
||||
<label for="scriptName"
|
||||
>Script Name <DocLink
|
||||
explanation="Useful if you would like to rename the collector script to prevent it blocked by AdBlockers."
|
||||
/></label
|
||||
>
|
||||
<input
|
||||
name="scriptName"
|
||||
id="scriptName"
|
||||
@ -21,9 +25,6 @@
|
||||
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>
|
||||
|
@ -14,7 +14,6 @@
|
||||
import { t } from '$lib/translations';
|
||||
import { appSession, disabledButton, status, location, setLocation, addToast } 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';
|
||||
@ -31,6 +30,7 @@
|
||||
import Moodle from './_Moodle.svelte';
|
||||
import Searxng from './_Searxng.svelte';
|
||||
import Weblate from './_Weblate.svelte';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
|
||||
const { id } = $page.params;
|
||||
$: isDisabled =
|
||||
@ -283,8 +283,9 @@
|
||||
</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')} />
|
||||
<label for="apiFqdn" class="pt-2 text-base font-bold text-stone-100"
|
||||
>API URL <DocLink explanation={$t('application.https_explainer')} /></label
|
||||
>
|
||||
</div>
|
||||
|
||||
<CopyPasswordField
|
||||
@ -302,9 +303,9 @@
|
||||
<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')} />
|
||||
>{$t('application.url_fqdn')}
|
||||
<DocLink explanation={$t('application.https_explainer')} />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<CopyPasswordField
|
||||
@ -364,7 +365,11 @@
|
||||
/>
|
||||
</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>
|
||||
<label for="exposePort" class="text-base font-bold text-stone-100"
|
||||
>Exposed Port <DocLink
|
||||
explanation={'You can expose your application to a port on the host system.<br><br>Useful if you would like to use your own reverse proxy or tunnel and also in development mode. Otherwise leave empty.'}
|
||||
/></label
|
||||
>
|
||||
<input
|
||||
readonly={!$appSession.isAdmin && !$status.service.isRunning}
|
||||
disabled={!$appSession.isAdmin ||
|
||||
@ -375,9 +380,6 @@
|
||||
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'}
|
||||
|
@ -1,7 +1,6 @@
|
||||
<script lang="ts">
|
||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
export let service: any;
|
||||
</script>
|
||||
|
||||
@ -13,7 +12,11 @@
|
||||
<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>
|
||||
<label for="umamiAdminPassword"
|
||||
>Initial Admin Password <DocLink
|
||||
explanation="It could be changed in Umami. <br>This is just the password set initially after the first start."
|
||||
/></label
|
||||
>
|
||||
<CopyPasswordField
|
||||
isPasswordField
|
||||
name="umamiAdminPassword"
|
||||
@ -23,7 +26,4 @@
|
||||
disabled
|
||||
readonly
|
||||
/>
|
||||
<Explainer
|
||||
text="It could be changed in Umami. <br>This is just the password set initially after the first start."
|
||||
/>
|
||||
</div>
|
||||
|
@ -3,12 +3,11 @@
|
||||
export let settings: any;
|
||||
import { page } from '$app/stores';
|
||||
import { getAPIUrl, getWebhookUrl, post } from '$lib/api';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import { t } from '$lib/translations';
|
||||
import { dashify, errorNotification, getDomain } from '$lib/common';
|
||||
import { addToast, appSession } from '$lib/store';
|
||||
import { dev } from '$app/env';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
import DocLink from '$lib/components/DocLink.svelte';
|
||||
|
||||
const { id } = $page.params;
|
||||
|
||||
@ -116,9 +115,11 @@ import DocLink from '$lib/components/DocLink.svelte';
|
||||
<input name="apiUrl" id="apiUrl" required bind:value={source.apiUrl} />
|
||||
</div>
|
||||
<div class="grid lg:grid-cols-2 items-center">
|
||||
<label for="customPort" class="text-base font-bold text-stone-100">Custom SSH Port <DocLink
|
||||
explanation={"If you use a self-hosted version of Git, you can provide custom port for all the Git related actions."}
|
||||
/></label>
|
||||
<label for="customPort" class="text-base font-bold text-stone-100"
|
||||
>Custom SSH Port <DocLink
|
||||
explanation={'If you use a self-hosted version of Git, you can provide custom port for all the Git related actions.'}
|
||||
/></label
|
||||
>
|
||||
<input
|
||||
name="customPort"
|
||||
id="customPort"
|
||||
@ -133,8 +134,8 @@ import DocLink from '$lib/components/DocLink.svelte';
|
||||
<label for="organization" class="pt-2 text-base font-bold text-stone-100"
|
||||
>Organization
|
||||
<DocLink
|
||||
explanation={"Fill it if you would like to use an organization's as your Git Source. Otherwise your user will be used."}
|
||||
/></label
|
||||
explanation={"Fill it if you would like to use an organization's as your Git Source. Otherwise your user will be used."}
|
||||
/></label
|
||||
>
|
||||
</div>
|
||||
<input
|
||||
@ -150,7 +151,7 @@ import DocLink from '$lib/components/DocLink.svelte';
|
||||
<form on:submit|preventDefault={handleSubmit} class="py-4">
|
||||
<div class="flex md:flex-row space-y-2 md:space-y-0 space-x-0 md:space-x-2 flex-col pb-5">
|
||||
<div class="title">{$t('general')}</div>
|
||||
|
||||
|
||||
{#if $appSession.isAdmin}
|
||||
<button class="btn btn-sm bg-sources" type="submit" disabled={loading}
|
||||
>{loading ? 'Saving...' : 'Save'}</button
|
||||
@ -196,7 +197,9 @@ import DocLink from '$lib/components/DocLink.svelte';
|
||||
{#if selfHosted}
|
||||
<div class="grid lg:grid-cols-2 items-center">
|
||||
<label for="customPort" class="text-base font-bold text-stone-100"
|
||||
>Custom SSH Port</label
|
||||
>Custom SSH Port <DocLink
|
||||
explanation="If you use a self-hosted version of Git, you can provide custom port for all the Git related actions."
|
||||
/></label
|
||||
>
|
||||
<input
|
||||
name="customPort"
|
||||
@ -206,9 +209,6 @@ import DocLink from '$lib/components/DocLink.svelte';
|
||||
required
|
||||
value={source.customPort}
|
||||
/>
|
||||
<Explainer
|
||||
text="If you use a self-hosted version of Git, you can provide custom port for all the Git related actions."
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="grid lg:grid-cols-2">
|
||||
|
Loading…
x
Reference in New Issue
Block a user