From 269250ef3d8b5e64025259cc4eaf761229ffbab2 Mon Sep 17 00:00:00 2001 From: Restray Date: Sat, 2 Apr 2022 21:08:55 +0200 Subject: [PATCH] Begin translation and finish i18n system --- .vscode/settings.json | 4 ++-- src/app.d.ts | 1 + src/hooks.ts | 28 +++++++++++++--------- src/lib/locales/en.json | 40 ++++++++++++++++++++++++++++++++ src/lib/locales/fr.json | 40 ++++++++++++++++++++++++++++++++ src/lib/translations.ts | 9 ++++--- src/routes/__layout.svelte | 11 ++++----- src/routes/index.svelte | 18 +++++++++----- src/routes/login/index.svelte | 19 ++++++++++----- src/routes/register/index.svelte | 15 ++++++------ static/locales/en.json | 16 ------------- static/locales/fr.json | 5 ---- svelte.config.js | 6 ----- 13 files changed, 142 insertions(+), 70 deletions(-) create mode 100644 src/lib/locales/en.json create mode 100644 src/lib/locales/fr.json delete mode 100644 static/locales/en.json delete mode 100644 static/locales/fr.json diff --git a/.vscode/settings.json b/.vscode/settings.json index ab2903b56..b823b0001 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,8 @@ { - "i18n-ally.localesPaths": ["static/locales"], + "i18n-ally.localesPaths": ["src/lib/locales"], "i18n-ally.keystyle": "nested", "i18n-ally.extract.ignoredByFiles": { "src\\routes\\__layout.svelte": ["Coolify", "coolLabs logo"] }, - "i18n-ally.sourceLanguage": "fr" + "i18n-ally.sourceLanguage": "en" } diff --git a/src/app.d.ts b/src/app.d.ts index 0557299b9..6dacd8395 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -23,6 +23,7 @@ interface SessionData { userId?: string | null; teamId?: string | null; permission?: string; + lang?: string; isAdmin?: boolean; expires?: string | null; gitlabToken?: string | null; diff --git a/src/hooks.ts b/src/hooks.ts index e0e4707cb..ac60a2a25 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -18,27 +18,22 @@ export const handle = handleSession( let response; const { url, request } = event; - const { pathname } = url; // Get defined locales const supportedLocales = locales.get(); let locale; - if (event.locals.cookies) { - locale = supportedLocales.find( - (l) => `${l}`.toLowerCase() === `${event.locals.cookies['lang']}`.toLowerCase() - ); - } - - if (!locale) { + if (event.locals.cookies['lang']) { + locale = event.locals.cookies['lang']; + } else if (!locale) { locale = `${`${request.headers.get('accept-language')}`.match( /[a-zA-Z]+?(?=-|_|,|;)/ )}`.toLowerCase(); - - // Set default locale if user preferred locale does not match - if (!supportedLocales.includes(locale)) locale = 'en'; } + // Set default locale if user preferred locale does not match + if (!supportedLocales.includes(locale)) locale = 'en'; + try { if (event.locals.cookies) { if (event.locals.cookies['kit.session']) { @@ -105,7 +100,18 @@ export const handle = handleSession( ); export const getSession: GetSession = function ({ locals }) { + // Get defined locales + const supportedLocales = locales.get(); + let locale; + + if (locals.cookies) { + locale = supportedLocales.find( + (l) => `${l}`.toLowerCase() === `${locals.cookies['lang']}`.toLowerCase() + ); + } + return { + lang: locale, version, ...locals.session.data }; diff --git a/src/lib/locales/en.json b/src/lib/locales/en.json new file mode 100644 index 000000000..a6a99215b --- /dev/null +++ b/src/lib/locales/en.json @@ -0,0 +1,40 @@ +{ + "layout": { + "update_done": "Update completed.", + "wait_new_version_startup": "Waiting for the new version to start...", + "new_version": "New version reachable. Reloading...", + "switch_to_a_different_team": "Switch to a different team...", + "update_available": "Update available" + }, + "error": { + "you_can_find_your_way_back": "You can find your way back", + "here": "here" + }, + "index": { + "dashboard": "Dashboard", + "applications": "Applications", + "destinations": "Destinations", + "git_sources": "Git Sources", + "databases": "Databases", + "services": "Services", + "teams": "Teams" + }, + "login": { + "already_logged_in": "Already logged in...", + "authenticating": "Authenticating...", + "login": "Login" + }, + "forms": { + "password": "Password", + "email": "Email", + "passwords_not_match": "Passwords do not match.", + "password_again": "Password again" + }, + "register": { + "register": "Register", + "first_user": "You are registering the first user. It will be the administrator of your Coolify instance." + }, + "reset": { + "reset_password": "Reset password" + } +} diff --git a/src/lib/locales/fr.json b/src/lib/locales/fr.json new file mode 100644 index 000000000..d52be9989 --- /dev/null +++ b/src/lib/locales/fr.json @@ -0,0 +1,40 @@ +{ + "index": { + "dashboard": "Tableau de bord", + "applications": "Applications", + "databases": "Bases de données", + "destinations": "Destinations", + "git_sources": "Sources Git", + "services": "Prestations de service", + "teams": "Équipes" + }, + "error": { + "here": "ici", + "you_can_find_your_way_back": "Tu peux retrouver ton chemin" + }, + "forms": { + "email": "E-mail", + "password": "Mot de passe", + "password_again": "Retaper le mot de passe", + "passwords_not_match": "Les mots de passe ne correspondent pas." + }, + "layout": { + "new_version": "Nouvelle version disponible. \nActualisation...", + "switch_to_a_different_team": "Changer d'équipe...", + "update_available": "Mise à jour disponible", + "update_done": "Mise à jour terminée.", + "wait_new_version_startup": "Attente du lancement de la nouvelle version..." + }, + "login": { + "already_logged_in": "Déjà connecté...", + "authenticating": "Authentification...", + "login": "Connexion" + }, + "register": { + "first_user": "Vous enregistrez le premier utilisateur. \nCe sera l'administrateur de votre instance Coolify.", + "register": "S'inscrire" + }, + "reset": { + "reset_password": "Réinitialiser le mot de passe" + } +} diff --git a/src/lib/translations.ts b/src/lib/translations.ts index 69282b21c..9d31f11bf 100644 --- a/src/lib/translations.ts +++ b/src/lib/translations.ts @@ -3,7 +3,6 @@ import lang from './lang.json'; /** @type {import('sveltekit-i18n').Config} */ const config = { - defaultLocale: 'en', fallbackLocale: 'en', translations: { en: { lang }, @@ -13,16 +12,16 @@ const config = { { locale: 'en', key: '', - loader: async () => (await import('../../static/locales/en.json')).default + loader: async () => (await import('./locales/en.json')).default }, { locale: 'fr', key: '', - loader: async () => (await import('../../static/locales/fr.json')).default + loader: async () => (await import('./locales/fr.json')).default } ] }; -export const { t, locale, locales, loading, loadTranslations } = new i18n(config); +export const { t, loading, locales, locale, loadTranslations } = new i18n(config); -loading.subscribe(($loading) => $loading && console.log('Loading translations...')); +loading.subscribe(($loading) => $loading); diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte index ceaf7cffb..7d6946b8d 100644 --- a/src/routes/__layout.svelte +++ b/src/routes/__layout.svelte @@ -4,6 +4,11 @@ import { locale, loadTranslations } from '$lib/translations'; export const load: Load = async ({ fetch, url, session }) => { + const { pathname } = url; + const initLocale = locale.get() || session.lang || 'en'; + + await loadTranslations(initLocale, pathname); + if (!session.userId && !publicPaths.includes(url.pathname)) { return { status: 302, @@ -16,12 +21,6 @@ const endpoint = `/teams.json`; const res = await fetch(endpoint); - const { pathname } = url; - const defaultLocale = session.lang; - const initLocale = locale.get() || defaultLocale; - - await loadTranslations(initLocale, pathname); - if (res.ok) { return { props: { diff --git a/src/routes/index.svelte b/src/routes/index.svelte index 2e3fc5137..ba7dd18a1 100644 --- a/src/routes/index.svelte +++ b/src/routes/index.svelte @@ -46,7 +46,7 @@ class="flex cursor-pointer flex-col rounded p-6 text-center text-green-500 no-underline transition duration-150 hover:bg-green-500 hover:text-white" >
- Applications + {$t('index.applications')}
{applicationsCount} @@ -58,7 +58,7 @@ class="flex cursor-pointer flex-col rounded p-6 text-center text-sky-500 no-underline transition duration-150 hover:bg-sky-500 hover:text-white" >
- Destinations + {$t('index.destinations')}
{destinationsCount} @@ -70,7 +70,7 @@ class="flex cursor-pointer flex-col rounded p-6 text-center text-orange-500 no-underline transition duration-150 hover:bg-orange-500 hover:text-white" >
- Git Sources + {$t('index.git_sources')}
{sourcesCount} @@ -81,7 +81,9 @@ sveltekit:prefetch class="flex cursor-pointer flex-col rounded p-6 text-center text-purple-500 no-underline transition duration-150 hover:bg-purple-500 hover:text-white" > -
Databases
+
+ {$t('index.databases')} +
{databasesCount}
-
Services
+
+ {$t('index.services')} +
{servicesCount}
@@ -98,7 +102,9 @@ sveltekit:prefetch class="flex cursor-pointer flex-col rounded p-6 text-center text-cyan-500 no-underline transition duration-150 hover:bg-cyan-500 hover:text-white" > -
Teams
+
+ {$t('index.teams')} +
{teamsCount}
diff --git a/src/routes/login/index.svelte b/src/routes/login/index.svelte index b321bc086..6b3c79679 100644 --- a/src/routes/login/index.svelte +++ b/src/routes/login/index.svelte @@ -4,6 +4,7 @@ import { session } from '$app/stores'; import { post } from '$lib/api'; import { errorNotification } from '$lib/form'; + import { t } from '$lib/translations'; import { onMount } from 'svelte'; let loading = false; let emailEl; @@ -37,9 +38,13 @@ } + + {$t('login.login')} + +
{#if $session.userId} -
Already logged in...
+
{$t('login.already_logged_in')}
{:else}
@@ -48,7 +53,7 @@ @@ -69,16 +74,18 @@ class="hover:opacity-90 text-white" class:bg-transparent={loading} class:text-stone-600={loading} - class:bg-coollabs={!loading}>{loading ? 'Authenticating...' : 'Login'}{loading ? $t('login.authenticating') : $t('login.login')} {$t('register.register')} goto('/reset')}>{$t('reset.reset_password')}
diff --git a/src/routes/register/index.svelte b/src/routes/register/index.svelte index 35501fce2..9de0626db 100644 --- a/src/routes/register/index.svelte +++ b/src/routes/register/index.svelte @@ -6,6 +6,7 @@ import { session } from '$app/stores'; import { post } from '$lib/api'; import { errorNotification } from '$lib/form'; + import { t } from '$lib/translations'; import { onMount } from 'svelte'; let loading = false; @@ -20,7 +21,7 @@ }); async function handleSubmit() { if (password !== passwordCheck) { - return errorNotification('Passwords do not match.'); + return errorNotification($t('forms.passwords_not_match')); } loading = true; try { @@ -57,7 +58,7 @@
{#if $session.userId} -
Already logged in...
+
{$t('login.already_logged_in')}
{:else}
@@ -66,7 +67,7 @@
{$t('register.register')}
{#if userCount === 0}
- You are registering the first user. It will be the administrator of your Coolify instance. + {$t('register.first_user')}
{/if} {/if} diff --git a/static/locales/en.json b/static/locales/en.json deleted file mode 100644 index f0f095a3b..000000000 --- a/static/locales/en.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "layout": { - "update_done": "Update completed.", - "wait_new_version_startup": "Waiting for the new version to start...", - "new_version": "New version reachable. Reloading...", - "switch_to_a_different_team": "Switch to a different team...", - "update_available": "Update available" - }, - "error": { - "you_can_find_your_way_back": "You can find your way back", - "here": "here" - }, - "index": { - "dashboard": "Dashboard" - } -} diff --git a/static/locales/fr.json b/static/locales/fr.json deleted file mode 100644 index 14f19dd47..000000000 --- a/static/locales/fr.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "index": { - "dashboard": "Tableau de bord" - } -} diff --git a/svelte.config.js b/svelte.config.js index 9d711910b..4e8bc8966 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -12,12 +12,6 @@ const config = { vite: { optimizeDeps: { exclude: ['svelte-kit-cookie-session'] - }, - server: { - fs: { - // Allow serving files from one level up to the project root - allow: ['../locales'] - } } } }