diff --git a/web/src/lib/components/admin-page/delete-confirm-dialogue.svelte b/web/src/lib/components/admin-page/delete-confirm-dialogue.svelte index 919fd333d3..6bc02046c5 100644 --- a/web/src/lib/components/admin-page/delete-confirm-dialogue.svelte +++ b/web/src/lib/components/admin-page/delete-confirm-dialogue.svelte @@ -5,7 +5,7 @@ import { serverConfig } from '$lib/stores/server-config.store'; import { createEventDispatcher } from 'svelte'; import Checkbox from '$lib/components/elements/checkbox.svelte'; - import { json, t } from 'svelte-i18n'; + import { t } from 'svelte-i18n'; import FormatMessage from '$lib/components/i18n/format-message.svelte'; export let user: UserResponseDto; @@ -55,14 +55,14 @@
{#if forceDelete}

- + {message}

{:else}

diff --git a/web/src/lib/components/admin-page/jobs/storage-migration-description.svelte b/web/src/lib/components/admin-page/jobs/storage-migration-description.svelte index 8b0a0f312a..8a74d2c5ad 100644 --- a/web/src/lib/components/admin-page/jobs/storage-migration-description.svelte +++ b/web/src/lib/components/admin-page/jobs/storage-migration-description.svelte @@ -1,11 +1,11 @@ diff --git a/web/src/lib/components/admin-page/restore-dialogue.svelte b/web/src/lib/components/admin-page/restore-dialogue.svelte index 4232aabdf9..9b274d2c2f 100644 --- a/web/src/lib/components/admin-page/restore-dialogue.svelte +++ b/web/src/lib/components/admin-page/restore-dialogue.svelte @@ -4,7 +4,7 @@ import { handleError } from '$lib/utils/handle-error'; import { restoreUserAdmin, type UserResponseDto } from '@immich/sdk'; import { createEventDispatcher } from 'svelte'; - import { json, t } from 'svelte-i18n'; + import { t } from 'svelte-i18n'; export let user: UserResponseDto; @@ -38,7 +38,7 @@ >

- + {message}

diff --git a/web/src/lib/components/admin-page/settings/auth/auth-settings.svelte b/web/src/lib/components/admin-page/settings/auth/auth-settings.svelte index da6b5057e7..a259dfb9b6 100644 --- a/web/src/lib/components/admin-page/settings/auth/auth-settings.svelte +++ b/web/src/lib/components/admin-page/settings/auth/auth-settings.svelte @@ -11,7 +11,7 @@ import { createEventDispatcher } from 'svelte'; import { fade } from 'svelte/transition'; import type { SettingsEventType } from '../admin-settings'; - import { json, t } from 'svelte-i18n'; + import { t } from 'svelte-i18n'; import FormatMessage from '$lib/components/i18n/format-message.svelte'; export let savedConfig: SystemConfigDto; @@ -53,7 +53,7 @@

Are you sure you want to disable all login methods? Login will be completely disabled.

- +

- +

- + {#if tag === 'h264-link'} {message} diff --git a/web/src/lib/components/admin-page/settings/library-settings/library-settings.svelte b/web/src/lib/components/admin-page/settings/library-settings/library-settings.svelte index 1ffda355de..e3c1734fb4 100644 --- a/web/src/lib/components/admin-page/settings/library-settings/library-settings.svelte +++ b/web/src/lib/components/admin-page/settings/library-settings/library-settings.svelte @@ -10,7 +10,7 @@ } from '$lib/components/shared-components/settings/setting-input-field.svelte'; import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte'; import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte'; - import { json, t } from 'svelte-i18n'; + import { t } from 'svelte-i18n'; import FormatMessage from '$lib/components/i18n/format-message.svelte'; export let savedConfig: SystemConfigDto; @@ -100,7 +100,7 @@ >

- + {message} diff --git a/web/src/lib/components/admin-page/settings/machine-learning-settings/machine-learning-settings.svelte b/web/src/lib/components/admin-page/settings/machine-learning-settings/machine-learning-settings.svelte index 72f8902bc6..ed26517fc3 100644 --- a/web/src/lib/components/admin-page/settings/machine-learning-settings/machine-learning-settings.svelte +++ b/web/src/lib/components/admin-page/settings/machine-learning-settings/machine-learning-settings.svelte @@ -12,7 +12,7 @@ import SettingSelect from '$lib/components/shared-components/settings/setting-select.svelte'; import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte'; import { featureFlags } from '$lib/stores/server-config.store'; - import { json, t } from 'svelte-i18n'; + import { t } from 'svelte-i18n'; import FormatMessage from '$lib/components/i18n/format-message.svelte'; export let savedConfig: SystemConfigDto; @@ -71,7 +71,7 @@ isEdited={config.machineLearning.clip.modelName !== savedConfig.machineLearning.clip.modelName} >

- + {message}

diff --git a/web/src/lib/components/admin-page/settings/storage-template/storage-template-settings.svelte b/web/src/lib/components/admin-page/settings/storage-template/storage-template-settings.svelte index 7e284ad8be..8aa1c2cb73 100644 --- a/web/src/lib/components/admin-page/settings/storage-template/storage-template-settings.svelte +++ b/web/src/lib/components/admin-page/settings/storage-template/storage-template-settings.svelte @@ -20,7 +20,7 @@ SettingInputFieldType, } from '$lib/components/shared-components/settings/setting-input-field.svelte'; import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte'; - import { json, t } from 'svelte-i18n'; + import { t } from 'svelte-i18n'; import FormatMessage from '$lib/components/i18n/format-message.svelte'; export let savedConfig: SystemConfigDto; @@ -89,7 +89,7 @@

- + {#if tag === 'template-link'} @@ -171,7 +171,7 @@

@@ -229,7 +229,7 @@

diff --git a/web/src/lib/components/i18n/__test__/format-message.spec.ts b/web/src/lib/components/i18n/__test__/format-message.spec.ts index 1449b3d4b7..be3e36bfa8 100644 --- a/web/src/lib/components/i18n/__test__/format-message.spec.ts +++ b/web/src/lib/components/i18n/__test__/format-message.spec.ts @@ -2,13 +2,10 @@ import FormatTagB from '$lib/components/i18n/__test__/format-tag-b.svelte'; import FormatMessage from '$lib/components/i18n/format-message.svelte'; import '@testing-library/jest-dom'; import { render, screen } from '@testing-library/svelte'; -import { init, json, locale, register, waitLocale } from 'svelte-i18n'; -import { get } from 'svelte/store'; +import { init, locale, register, waitLocale } from 'svelte-i18n'; import { describe } from 'vitest'; describe('FormatMessage component', () => { - let $json: (id: string, locale?: string | undefined) => unknown; - beforeAll(async () => { register('en', () => Promise.resolve({ @@ -21,12 +18,11 @@ describe('FormatMessage component', () => { await init({ fallbackLocale: 'en' }); await waitLocale('en'); - $json = get(json); }); it('formats a plain text message', () => { render(FormatMessage, { - message: $json('hello'), + key: 'hello', values: { name: 'test' }, }); expect(screen.getByText('Hello test')).toBeInTheDocument(); @@ -34,20 +30,20 @@ describe('FormatMessage component', () => { it('throws an error when locale is empty', async () => { await locale.set(undefined); - expect(() => render(FormatMessage, { message: undefined })).toThrowError(); + expect(() => render(FormatMessage, { key: '' })).toThrowError(); await locale.set('en'); }); it('shows raw message when value is empty', () => { render(FormatMessage, { - message: $json('hello'), + key: 'hello', }); expect(screen.getByText('Hello {name}')).toBeInTheDocument(); }); it('shows message when slot is empty', () => { render(FormatMessage, { - message: $json('html'), + key: 'html', values: { name: 'test' }, }); expect(screen.getByText('Hello test')).toBeInTheDocument(); @@ -55,7 +51,7 @@ describe('FormatMessage component', () => { it('renders a message with html', () => { const { container } = render(FormatTagB, { - message: $json('html'), + key: 'html', values: { name: 'test' }, }); expect(container.innerHTML).toBe('Hello test'); @@ -63,7 +59,7 @@ describe('FormatMessage component', () => { it('renders a message with html and plural', () => { const { container } = render(FormatTagB, { - message: $json('plural'), + key: 'plural', values: { count: 1 }, }); expect(container.innerHTML).toBe('You have 1 item'); @@ -71,8 +67,13 @@ describe('FormatMessage component', () => { it('protects agains XSS injection', () => { render(FormatMessage, { - message: $json('xss'), + key: 'xss', }); expect(screen.getByText('')).toBeInTheDocument(); }); + + it('displays the message key when not found', () => { + render(FormatMessage, { key: 'invalid.key' }); + expect(screen.getByText('invalid.key')).toBeInTheDocument(); + }); }); diff --git a/web/src/lib/components/i18n/__test__/format-tag-b.svelte b/web/src/lib/components/i18n/__test__/format-tag-b.svelte index c7017eabef..f06a54a1e0 100644 --- a/web/src/lib/components/i18n/__test__/format-tag-b.svelte +++ b/web/src/lib/components/i18n/__test__/format-tag-b.svelte @@ -2,11 +2,11 @@ import FormatMessage from '../format-message.svelte'; import type { ComponentProps } from 'svelte'; - export let message: unknown; + export let key: string; export let values: ComponentProps['values']; - + {#if tag === 'b'} {message} {/if} diff --git a/web/src/lib/components/i18n/format-message.svelte b/web/src/lib/components/i18n/format-message.svelte index 5bf3c14c32..62ccead471 100644 --- a/web/src/lib/components/i18n/format-message.svelte +++ b/web/src/lib/components/i18n/format-message.svelte @@ -1,11 +1,11 @@ diff --git a/web/src/lib/components/onboarding-page/onboarding-storage-template.svelte b/web/src/lib/components/onboarding-page/onboarding-storage-template.svelte index 193adb3e4d..e8f3542f5d 100644 --- a/web/src/lib/components/onboarding-page/onboarding-storage-template.svelte +++ b/web/src/lib/components/onboarding-page/onboarding-storage-template.svelte @@ -9,7 +9,7 @@ import Button from '../elements/buttons/button.svelte'; import Icon from '../elements/icon.svelte'; import OnboardingCard from './onboarding-card.svelte'; - import { json, t } from 'svelte-i18n'; + import { t } from 'svelte-i18n'; import FormatMessage from '$lib/components/i18n/format-message.svelte'; const dispatch = createEventDispatcher<{ @@ -30,7 +30,7 @@

- + {message}

diff --git a/web/src/lib/components/shared-components/version-announcement-box.svelte b/web/src/lib/components/shared-components/version-announcement-box.svelte index 5f4b5557dd..ff161f1eeb 100644 --- a/web/src/lib/components/shared-components/version-announcement-box.svelte +++ b/web/src/lib/components/shared-components/version-announcement-box.svelte @@ -3,7 +3,7 @@ import type { ServerVersionResponseDto } from '@immich/sdk'; import Button from '../elements/buttons/button.svelte'; import FullScreenModal from './full-screen-modal.svelte'; - import { json, t } from 'svelte-i18n'; + import { t } from 'svelte-i18n'; import FormatMessage from '$lib/components/i18n/format-message.svelte'; let showModal = false; @@ -37,7 +37,7 @@ {#if showModal} (showModal = false)}>
- + {#if tag === 'link'}