ui: redesign a lot
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { toast } from '@zerodevx/svelte-toast';
|
||||
import { addToast } from '$lib/store';
|
||||
|
||||
export const supportedServiceTypesAndVersions = [
|
||||
{
|
||||
@@ -167,12 +167,20 @@ export const asyncSleep = (delay: number) =>
|
||||
export function errorNotification(error: any): void {
|
||||
if (error.message) {
|
||||
if (error.message === 'Cannot read properties of undefined (reading \'postMessage\')') {
|
||||
toast.push('Currently there is background process in progress. Please try again later.');
|
||||
return;
|
||||
return addToast({
|
||||
message: 'Currently there is background process in progress. Please try again later.',
|
||||
type: 'error',
|
||||
});
|
||||
}
|
||||
toast.push(error.message);
|
||||
addToast({
|
||||
message: error.message,
|
||||
type: 'error',
|
||||
});
|
||||
} else {
|
||||
toast.push('Ooops, something is not okay, are you okay?');
|
||||
addToast({
|
||||
message: 'Ooops, something is not okay, are you okay?',
|
||||
type: 'error',
|
||||
});
|
||||
}
|
||||
console.error(JSON.stringify(error));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { browser } from '$app/env';
|
||||
import { addToast } from '$lib/store';
|
||||
import { toast } from '@zerodevx/svelte-toast';
|
||||
let showPassword = false;
|
||||
|
||||
@@ -20,7 +21,10 @@
|
||||
function copyToClipboard() {
|
||||
if (isHttps && navigator.clipboard) {
|
||||
navigator.clipboard.writeText(value);
|
||||
toast.push('Copied to clipboard.');
|
||||
addToast({
|
||||
message: 'Copied to clipboard.',
|
||||
type: 'success',
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
52
apps/ui/src/lib/components/Toast.svelte
Normal file
52
apps/ui/src/lib/components/Toast.svelte
Normal file
@@ -0,0 +1,52 @@
|
||||
<script>
|
||||
export let type = 'info';
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="alert shadow-lg text-white rounded"
|
||||
class:alert-success={type === 'success'}
|
||||
class:alert-error={type === 'error'}
|
||||
class:alert-info={type === 'info'}
|
||||
>
|
||||
{#if type === 'success'}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="stroke-current flex-shrink-0 h-6 w-6"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
><path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/></svg
|
||||
>
|
||||
{:else if type === 'error'}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="stroke-current flex-shrink-0 h-6 w-6"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
><path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/></svg
|
||||
>
|
||||
{:else if type === 'info'}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
class="stroke-current flex-shrink-0 w-6 h-6"
|
||||
><path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/></svg
|
||||
>
|
||||
{/if}
|
||||
<slot />
|
||||
</div>
|
||||
22
apps/ui/src/lib/components/Toasts.svelte
Normal file
22
apps/ui/src/lib/components/Toasts.svelte
Normal file
@@ -0,0 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { fade } from 'svelte/transition';
|
||||
import Toast from './Toast.svelte';
|
||||
|
||||
import { toasts } from '$lib/store';
|
||||
</script>
|
||||
|
||||
{#if $toasts}
|
||||
<section>
|
||||
<article class="toast toast-bottom toast-end rounded-none" role="alert" transition:fade>
|
||||
{#each $toasts as toast (toast.id)}
|
||||
<Toast type={toast.type}>{toast.message}</Toast>
|
||||
{/each}
|
||||
</article>
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
<style lang="postcss">
|
||||
section {
|
||||
@apply fixed top-0 left-0 right-0 w-full flex flex-col mt-4 justify-center z-[1000];
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { dev } from '$app/env';
|
||||
import { get, post } from '$lib/api';
|
||||
import { appSession, features } from '$lib/store';
|
||||
import { addToast, appSession, features } from '$lib/store';
|
||||
import { toast } from '@zerodevx/svelte-toast';
|
||||
import { asyncSleep, errorNotification } from '$lib/common';
|
||||
import { onMount } from 'svelte';
|
||||
@@ -22,7 +22,11 @@
|
||||
return window.location.reload();
|
||||
} else {
|
||||
await post(`/update`, { type: 'update', latestVersion });
|
||||
toast.push('Update completed.<br><br>Waiting for the new version to start...');
|
||||
addToast({
|
||||
message: 'Update completed.<br><br>Waiting for the new version to start...',
|
||||
type: 'success'
|
||||
});
|
||||
|
||||
let reachable = false;
|
||||
let tries = 0;
|
||||
do {
|
||||
@@ -36,7 +40,10 @@
|
||||
if (reachable) break;
|
||||
tries++;
|
||||
} while (!reachable || tries < 120);
|
||||
toast.push('New version reachable. Reloading...');
|
||||
addToast({
|
||||
message: 'New version reachable. Reloading...',
|
||||
type: 'success'
|
||||
});
|
||||
updateStatus.loading = false;
|
||||
updateStatus.success = true;
|
||||
await asyncSleep(3000);
|
||||
|
||||
@@ -19,9 +19,10 @@
|
||||
};
|
||||
let usageInterval: any;
|
||||
let loading = {
|
||||
usage: false
|
||||
usage: false,
|
||||
cleanup: false
|
||||
};
|
||||
import { appSession } from '$lib/store';
|
||||
import { addToast, appSession } from '$lib/store';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { get, post } from '$lib/api';
|
||||
import { errorNotification } from '$lib/common';
|
||||
@@ -60,7 +61,18 @@
|
||||
disk: 'stable'
|
||||
};
|
||||
async function manuallyCleanupStorage() {
|
||||
return await post('/internal/cleanup', {});
|
||||
try {
|
||||
loading.cleanup = true
|
||||
await post('/internal/cleanup', {});
|
||||
return addToast({
|
||||
message: "Cleanup done.",
|
||||
type:"success"
|
||||
})
|
||||
} catch(error) {
|
||||
return errorNotification(error);
|
||||
} finally {
|
||||
loading.cleanup = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -132,7 +144,7 @@
|
||||
<dd class="mt-1 text-3xl font-semibold text-white">
|
||||
{usage?.disk.usedGb}<span class="text-sm">GB</span>
|
||||
</dd>
|
||||
<button on:click={manuallyCleanupStorage} class="bg-coollabs hover:bg-coollabs-100"
|
||||
<button on:click={manuallyCleanupStorage} class:loading={loading.cleanup} class="btn btn-sm"
|
||||
>Cleanup Storage</button
|
||||
>
|
||||
</div>
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
"removing": "Removing...",
|
||||
"remove_domain": "Remove domain",
|
||||
"public_port_range": "Public Port Range",
|
||||
"public_port_range_explainer": "Ports used to expose databases/services/internal services.<br> Add them to your firewall (if applicable).<br><br>You can specify a range of ports, eg: <span class='text-yellow-500 font-bold'>9000-9100</span>",
|
||||
"public_port_range_explainer": "Ports used to expose databases/services/internal services.<br> Add them to your firewall (if applicable).<br><br>You can specify a range of ports, eg: <span class='text-settings font-bold'>9000-9100</span>",
|
||||
"no_actions_available": "No actions available",
|
||||
"admin_api_key": "Admin API key"
|
||||
},
|
||||
@@ -144,8 +144,8 @@
|
||||
},
|
||||
"preview": {
|
||||
"need_during_buildtime": "Need during buildtime?",
|
||||
"setup_secret_app_first": "You can add secrets to PR/MR deployments. Please add secrets to the application first. <br>Useful for creating <span class='text-green-500 font-bold'>staging</span> environments.",
|
||||
"values_overwriting_app_secrets": "These values overwrite application secrets in PR/MR deployments. Useful for creating <span class='text-green-500 font-bold'>staging</span> environments.",
|
||||
"setup_secret_app_first": "You can add secrets to PR/MR deployments. Please add secrets to the application first. <br>Useful for creating <span class='text-applications font-bold'>staging</span> environments.",
|
||||
"values_overwriting_app_secrets": "These values overwrite application secrets in PR/MR deployments. Useful for creating <span class='text-applications font-bold'>staging</span> environments.",
|
||||
"redeploy": "Redeploy",
|
||||
"no_previews_available": "No previews available"
|
||||
},
|
||||
@@ -194,14 +194,14 @@
|
||||
"application": "Application",
|
||||
"url_fqdn": "URL (FQDN)",
|
||||
"domain_fqdn": "Domain (FQDN)",
|
||||
"https_explainer": "If you specify <span class='text-green-500 font-bold'>https</span>, the application will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-green-500 font-bold'>www</span>, the application will be redirected (302) from non-www and vice versa.<br><br>To modify the domain, you must first stop the application.<br><br><span class='text-white font-bold'>You must set your DNS to point to the server IP in advance.</span>",
|
||||
"https_explainer": "If you specify <span class='text-applications font-bold'>https</span>, the application will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-applications font-bold'>www</span>, the application will be redirected (302) from non-www and vice versa.<br><br>To modify the domain, you must first stop the application.<br><br><span class='text-white font-bold'>You must set your DNS to point to the server IP in advance.</span>",
|
||||
"ssl_www_and_non_www": "Generate SSL for www and non-www?",
|
||||
"ssl_explainer": "It will generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-green-500'>both DNS entries</span> set in advance.<br><br>Useful if you expect to have visitors on both.",
|
||||
"ssl_explainer": "It will generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-applications'>both DNS entries</span> set in advance.<br><br>Useful if you expect to have visitors on both.",
|
||||
"install_command": "Install Command",
|
||||
"build_command": "Build Command",
|
||||
"start_command": "Start Command",
|
||||
"directory_to_use_explainer": "Directory to use as the base for all commands.<br>Could be useful with <span class='text-green-500 font-bold'>monorepos</span>.",
|
||||
"publish_directory_explainer": "Directory containing all the assets for deployment. <br> For example: <span class='text-green-500 font-bold'>dist</span>,<span class='text-green-500 font-bold'>_site</span> or <span class='text-green-500 font-bold'>public</span>.",
|
||||
"directory_to_use_explainer": "Directory to use as the base for all commands.<br>Could be useful with <span class='text-applications font-bold'>monorepos</span>.",
|
||||
"publish_directory_explainer": "Directory containing all the assets for deployment. <br> For example: <span class='text-applications font-bold'>dist</span>,<span class='text-applications font-bold'>_site</span> or <span class='text-applications font-bold'>public</span>.",
|
||||
"features": "Features",
|
||||
"enable_automatic_deployment": "Enable Automatic Deployment",
|
||||
"enable_auto_deploy_webhooks": "Enable automatic deployment through webhooks.",
|
||||
@@ -306,7 +306,7 @@
|
||||
"change_language": "Change Language",
|
||||
"permission_denied": "You do not have permission to do this. \\nAsk an admin to modify your permissions.",
|
||||
"domain_removed": "Domain removed",
|
||||
"ssl_explainer": "If you specify <span class='text-yellow-500 font-bold'>https</span>, Coolify will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-yellow-500 font-bold'>www</span>, Coolify will be redirected (302) from non-www and vice versa.<br><br><span class='text-yellow-500 font-bold'>WARNING:</span> If you change an already set domain, it will brake webhooks and other integrations! You need to manually update them.",
|
||||
"ssl_explainer": "If you specify <span class='text-settings font-bold'>https</span>, Coolify will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-settings font-bold'>www</span>, Coolify will be redirected (302) from non-www and vice versa.<br><br><span class='text-settings font-bold'>WARNING:</span> If you change an already set domain, it will brake webhooks and other integrations! You need to manually update them.",
|
||||
"must_remove_domain_before_changing": "Must remove the domain before you can change this setting.",
|
||||
"registration_allowed": "Registration allowed?",
|
||||
"registration_allowed_explainer": "Allow further registrations to the application. <br>It's turned off after the first registration.",
|
||||
@@ -314,7 +314,7 @@
|
||||
"credential_stat_explainer": "Credentials for <a class=\"text-white font-bold\" href=\"{{link}}\" target=\"_blank\">stats</a> page.",
|
||||
"auto_update_enabled": "Auto update enabled?",
|
||||
"auto_update_enabled_explainer": "Enable automatic updates for Coolify. It will be done automatically behind the scenes, if there is no build process running.",
|
||||
"generate_www_non_www_ssl": "It will generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-yellow-500'>both DNS entries</span> set in advance.",
|
||||
"generate_www_non_www_ssl": "It will generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-settings'>both DNS entries</span> set in advance.",
|
||||
"is_dns_check_enabled": "DNS check enabled?",
|
||||
"is_dns_check_enabled_explainer": "You can disable DNS check before creating SSL certificates.<br><br>Turning it off is useful when Coolify is behind a reverse proxy or tunnel."
|
||||
},
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
"delete_application": "Supprimer l'application",
|
||||
"deployment_queued": "Déploiement en file d'attente.",
|
||||
"destination": "Destination",
|
||||
"directory_to_use_explainer": "Répertoire à utiliser comme base pour toutes les commandes.<br>Pourrait être utile avec <span class='text-green-500 font-bold'>monorepos</span>.",
|
||||
"directory_to_use_explainer": "Répertoire à utiliser comme base pour toutes les commandes.<br>Pourrait être utile avec <span class='text-applications font-bold'>monorepos</span>.",
|
||||
"dns_not_set_error": "DNS non défini ou propagé pour {{domain}}.<br><br>Veuillez vérifier vos paramètres DNS.",
|
||||
"dns_not_set_partial_error": "DNS non défini",
|
||||
"domain_already_in_use": "Le domaine {{domain}} est déjà utilisé.",
|
||||
@@ -65,7 +65,7 @@
|
||||
"features": "Caractéristiques",
|
||||
"git_repository": "Dépôt Git",
|
||||
"git_source": "Source Git",
|
||||
"https_explainer": "Si vous spécifiez <span class='text-green-500 font-bold'>https</span>, l'application sera accessible uniquement via https. \nUn certificat SSL sera généré pour vous.<br>Si vous spécifiez <span class='text-green-500 font-bold'>www</span>, l'application sera redirigée (302) à partir de non-www et vice versa \n.<br><br>Pour modifier le domaine, vous devez d'abord arrêter l'application.<br><br><span class='text-white font-bold'>Vous devez configurer, en avance, votre DNS pour pointer vers l'IP du serveur.</span>",
|
||||
"https_explainer": "Si vous spécifiez <span class='text-applications font-bold'>https</span>, l'application sera accessible uniquement via https. \nUn certificat SSL sera généré pour vous.<br>Si vous spécifiez <span class='text-applications font-bold'>www</span>, l'application sera redirigée (302) à partir de non-www et vice versa \n.<br><br>Pour modifier le domaine, vous devez d'abord arrêter l'application.<br><br><span class='text-white font-bold'>Vous devez configurer, en avance, votre DNS pour pointer vers l'IP du serveur.</span>",
|
||||
"install_command": "Commande d'installation",
|
||||
"logs": "Journaux des applications",
|
||||
"no_applications_found": "Aucune application trouvée",
|
||||
@@ -78,11 +78,11 @@
|
||||
"need_during_buildtime": "Besoin pendant la build ?",
|
||||
"no_previews_available": "Aucun aperçu disponible",
|
||||
"redeploy": "Redéployer",
|
||||
"setup_secret_app_first": "Vous pouvez ajouter des secrets aux déploiements PR/MR. \nVeuillez d'abord ajouter des secrets à l'application. \n<br>Utile pour créer des environnements <span class='text-green-500 font-bold'>de mise en scène</span>.",
|
||||
"values_overwriting_app_secrets": "Ces valeurs remplacent les secrets d'application dans les déploiements PR/MR. \nUtile pour créer des environnements <span class='text-green-500 font-bold'>de mise en scène</span>."
|
||||
"setup_secret_app_first": "Vous pouvez ajouter des secrets aux déploiements PR/MR. \nVeuillez d'abord ajouter des secrets à l'application. \n<br>Utile pour créer des environnements <span class='text-applications font-bold'>de mise en scène</span>.",
|
||||
"values_overwriting_app_secrets": "Ces valeurs remplacent les secrets d'application dans les déploiements PR/MR. \nUtile pour créer des environnements <span class='text-applications font-bold'>de mise en scène</span>."
|
||||
},
|
||||
"previews": "Aperçus",
|
||||
"publish_directory_explainer": "Répertoire contenant tous les actifs à déployer. \n<br> Par exemple : <span class='text-green-500 font-bold'>dist</span>,<span class='text-green-500 font-bold'>_site</span> ou <span \nclass='text-green-500 font-bold'>public</span>.",
|
||||
"publish_directory_explainer": "Répertoire contenant tous les actifs à déployer. \n<br> Par exemple : <span class='text-applications font-bold'>dist</span>,<span class='text-applications font-bold'>_site</span> ou <span \nclass='text-applications font-bold'>public</span>.",
|
||||
"rebuild_application": "Re-build l'application",
|
||||
"secret": "secrets",
|
||||
"secrets": {
|
||||
@@ -91,7 +91,7 @@
|
||||
"use_isbuildsecret": "Utiliser isBuildSecret"
|
||||
},
|
||||
"settings_saved": "Paramètres sauvegardés.",
|
||||
"ssl_explainer": "Il générera des certificats pour www et non-www. \n<br>Vous devez avoir <span class='font-bold text-green-500'>les deux entrées DNS</span> définies à l'avance.<br><br>Utile si vous prévoyez d'avoir des visiteurs sur les deux.",
|
||||
"ssl_explainer": "Il générera des certificats pour www et non-www. \n<br>Vous devez avoir <span class='font-bold text-applications'>les deux entrées DNS</span> définies à l'avance.<br><br>Utile si vous prévoyez d'avoir des visiteurs sur les deux.",
|
||||
"ssl_www_and_non_www": "Générer SSL pour www et non-www ?",
|
||||
"start_command": "Démarrer la commande",
|
||||
"stop_application": "Arrêter l'application",
|
||||
@@ -181,7 +181,7 @@
|
||||
"path": "Chemin",
|
||||
"port": "Port",
|
||||
"public_port_range": "Gamme de ports publics",
|
||||
"public_port_range_explainer": "Ports utilisés pour exposer les bases de données/services/services internes.<br> Ajoutez-les à votre pare-feu (le cas échéant).<br><br>Vous pouvez spécifier une plage de ports, par exemple : <span class='text-yellow-500 \nfont-bold'>9000-9100</span>",
|
||||
"public_port_range_explainer": "Ports utilisés pour exposer les bases de données/services/services internes.<br> Ajoutez-les à votre pare-feu (le cas échéant).<br><br>Vous pouvez spécifier une plage de ports, par exemple : <span class='text-settings \nfont-bold'>9000-9100</span>",
|
||||
"publish_directory": "Publier le répertoire",
|
||||
"remove": "Retirer",
|
||||
"remove_domain": "Supprimer le domaine",
|
||||
@@ -266,7 +266,7 @@
|
||||
"permission_denied": "Vous n'avez pas la permission de faire cela. \n\\nDemandez à un administrateur de modifier vos autorisations.",
|
||||
"registration_allowed": "Inscription autorisée ?",
|
||||
"registration_allowed_explainer": "Autoriser d'autres inscriptions à l'application. \n<br>Il est désactivé après la première inscription.",
|
||||
"ssl_explainer": "Si vous spécifiez <span class='text-yellow-500 font-bold'>https</span>, Coolify sera accessible uniquement via https. \nUn certificat SSL sera généré pour vous.<br>Si vous spécifiez <span class='text-yellow-500 font-bold'>www</span>, Coolify sera redirigé (302) à partir de non-www et vice versa."
|
||||
"ssl_explainer": "Si vous spécifiez <span class='text-settings font-bold'>https</span>, Coolify sera accessible uniquement via https. \nUn certificat SSL sera généré pour vous.<br>Si vous spécifiez <span class='text-settings font-bold'>www</span>, Coolify sera redirigé (302) à partir de non-www et vice versa."
|
||||
},
|
||||
"source": {
|
||||
"application_id": "ID d'application",
|
||||
|
||||
@@ -17,6 +17,11 @@ interface AppSession {
|
||||
gitlab: string | null,
|
||||
}
|
||||
}
|
||||
interface AddToast {
|
||||
type?: "info" | "success" | "error",
|
||||
message: string,
|
||||
timeout?: number | undefined
|
||||
}
|
||||
export const loginEmail: Writable<string | undefined> = writable()
|
||||
export const appSession: Writable<AppSession> = writable({
|
||||
ipv4: null,
|
||||
@@ -74,4 +79,30 @@ export const setLocation = (resource: any) => {
|
||||
} else {
|
||||
location.set(resource.fqdn)
|
||||
}
|
||||
}
|
||||
|
||||
export const toasts: any = writable([])
|
||||
|
||||
export const dismissToast = (id: number) => {
|
||||
toasts.update((all: any) => all.filter((t: any) => t.id !== id))
|
||||
}
|
||||
|
||||
export const addToast = (toast: AddToast) => {
|
||||
// Create a unique ID so we can easily find/remove it
|
||||
// if it is dismissible/has a timeout.
|
||||
const id = Math.floor(Math.random() * 10000)
|
||||
|
||||
// Setup some sensible defaults for a toast.
|
||||
const defaults = {
|
||||
id,
|
||||
type: 'info',
|
||||
timeout: 2000,
|
||||
}
|
||||
|
||||
// Push the toast to the top of the list of toasts
|
||||
const t = { ...defaults, ...toast }
|
||||
toasts.update((all: any) => [t, ...all])
|
||||
|
||||
// If toast is dismissible, dismiss it after "timeout" amount of time.
|
||||
if (t.timeout) setTimeout(() => dismissToast(id), t.timeout)
|
||||
}
|
||||
Reference in New Issue
Block a user