feat(web): translations (#9854)

* First test

* Added translation using Weblate (French)

* Translated using Weblate (German)

Currently translated at 100.0% (4 of 4 strings)

Translation: immich/web
Translate-URL: http://familie-mach.net/projects/immich/web/de/

* Translated using Weblate (French)

Currently translated at 100.0% (4 of 4 strings)

Translation: immich/web
Translate-URL: http://familie-mach.net/projects/immich/web/fr/

* Further testing

* Further testing

* Translated using Weblate (German)

Currently translated at 100.0% (18 of 18 strings)

Translation: immich/web
Translate-URL: http://familie-mach.net/projects/immich/web/de/

* Further work

* Update string file.

* More strings

* Automatically changed strings

* Add automatically translated german file for testing purposes

* Fix merge-face-selector component

* Make server stats strings uppercase

* Fix uppercase string

* Fix some strings in jobs-panel

* Fix lower and uppercase strings. Add a few additional string. Fix a few unnecessary replacements

* Update german test translations

* Fix typo in locales file

* Change string keys

* Extract more strings

* Extract and replace some more strings

* Update testtranslationfile

* Change translation keys

* Fix rebase errors

* Fix one more rebase error

* Remove german translation file

* Co-authored-by: Daniel Dietzler <danieldietzler@users.noreply.github.com>

* chore: clean up translations

* chore: add new line

* fix formatting

* chore: fixes

* fix: loading and tests

---------

Co-authored-by: root <root@Blacki>
Co-authored-by: admin <admin@example.com>
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
This commit is contained in:
Manic-87 2024-06-04 21:53:00 +02:00 committed by GitHub
parent a2bccf23c9
commit f446bc8caa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
177 changed files with 2779 additions and 1017 deletions

View file

@ -5,6 +5,7 @@
import { handleError } from '../../utils/handle-error';
import Button from '../elements/buttons/button.svelte';
import PasswordField from '../shared-components/password-field.svelte';
import { t } from 'svelte-i18n';
let email = '';
let password = '';
@ -16,7 +17,7 @@
$: {
if (password !== confirmPassword && confirmPassword.length > 0) {
errorMessage = 'Password does not match';
errorMessage = $t('password_does_not_match');
canRegister = false;
} else {
errorMessage = '';
@ -32,8 +33,8 @@
await signUpAdmin({ signUpDto: { email, password, name } });
await goto(AppRoute.AUTH_LOGIN);
} catch (error) {
handleError(error, 'Unable to create admin account');
errorMessage = 'Error create admin account';
handleError(error, 'errors.errors.unable_to_create_admin_account');
errorMessage = $t('errors.errors.unable_to_create_admin_account');
}
}
}
@ -41,22 +42,22 @@
<form on:submit|preventDefault={registerAdmin} method="post" class="mt-5 flex flex-col gap-5">
<div class="flex flex-col gap-2">
<label class="immich-form-label" for="email">Admin Email</label>
<label class="immich-form-label" for="email">{$t('admin_email')}</label>
<input class="immich-form-input" id="email" bind:value={email} type="email" autocomplete="email" required />
</div>
<div class="flex flex-col gap-2">
<label class="immich-form-label" for="password">Admin Password</label>
<label class="immich-form-label" for="password">{$t('admin_password')}</label>
<PasswordField id="password" bind:password autocomplete="new-password" />
</div>
<div class="flex flex-col gap-2">
<label class="immich-form-label" for="confirmPassword">Confirm Admin Password</label>
<label class="immich-form-label" for="confirmPassword">{$t('confirm_admin_password')}</label>
<PasswordField id="confirmPassword" bind:password={confirmPassword} autocomplete="new-password" />
</div>
<div class="flex flex-col gap-2">
<label class="immich-form-label" for="name">Name</label>
<label class="immich-form-label" for="name">{$t('name')}</label>
<input class="immich-form-input" id="name" bind:value={name} type="text" autocomplete="name" required />
</div>
@ -65,6 +66,6 @@
{/if}
<div class="my-5 flex w-full">
<Button type="submit" size="lg" fullwidth>Sign up</Button>
<Button type="submit" size="lg" fullwidth>{$t('sign_up')}</Button>
</div>
</form>

View file

@ -5,11 +5,12 @@
import Button from '../elements/buttons/button.svelte';
import FullScreenModal from '../shared-components/full-screen-modal.svelte';
import { NotificationType, notificationController } from '../shared-components/notification/notification';
import { t } from 'svelte-i18n';
export let apiKey: Partial<ApiKeyResponseDto>;
export let title: string;
export let cancelText = 'Cancel';
export let submitText = 'Save';
export let cancelText = $t('cancel');
export let submitText = $t('save');
const dispatch = createEventDispatcher<{
cancel: void;
@ -31,7 +32,7 @@
<FullScreenModal {title} icon={mdiKeyVariant} onClose={handleCancel}>
<form on:submit|preventDefault={handleSubmit} autocomplete="off" id="api-key-form">
<div class="mb-4 flex flex-col gap-2">
<label class="immich-form-label" for="name">Name</label>
<label class="immich-form-label" for="name">{$t('name')}</label>
<input class="immich-form-input" id="name" name="name" type="text" bind:value={apiKey.name} />
</div>
</form>

View file

@ -4,6 +4,7 @@
import { createEventDispatcher } from 'svelte';
import Button from '../elements/buttons/button.svelte';
import FullScreenModal from '../shared-components/full-screen-modal.svelte';
import { t } from 'svelte-i18n';
export let secret = '';
@ -13,7 +14,7 @@
const handleDone = () => dispatch('done');
</script>
<FullScreenModal title="API key" icon={mdiKeyVariant} onClose={() => handleDone()}>
<FullScreenModal title={$t('api_key')} icon={mdiKeyVariant} onClose={() => handleDone()}>
<div class="text-immich-primary dark:text-immich-dark-primary">
<p class="text-sm dark:text-immich-dark-fg">
This value will only be shown once. Please be sure to copy it before closing the window.
@ -21,12 +22,12 @@
</div>
<div class="my-4 flex flex-col gap-2">
<!-- <label class="immich-form-label" for="secret">API Key</label> -->
<!-- <label class="immich-form-label" for="secret">{ $t("api_key") }</label> -->
<textarea class="immich-form-input" id="secret" name="secret" readonly={true} value={secret} />
</div>
<svelte:fragment slot="sticky-bottom">
<Button on:click={() => copyToClipboard(secret)} fullwidth>Copy to Clipboard</Button>
<Button on:click={() => handleDone()} fullwidth>Done</Button>
<Button on:click={() => copyToClipboard(secret)} fullwidth>{$t('copy_to_clipboard')}</Button>
<Button on:click={() => handleDone()} fullwidth>{$t('done')}</Button>
</svelte:fragment>
</FullScreenModal>

View file

@ -3,6 +3,7 @@
import Button from '../elements/buttons/button.svelte';
import PasswordField from '../shared-components/password-field.svelte';
import { updateMyUser } from '@immich/sdk';
import { t } from 'svelte-i18n';
let errorMessage: string;
let success: string;
@ -14,7 +15,7 @@
$: {
if (password !== passwordConfirm && passwordConfirm.length > 0) {
errorMessage = 'Password does not match';
errorMessage = $t('password_does_not_match');
valid = false;
} else {
errorMessage = '';
@ -39,12 +40,12 @@
<form on:submit|preventDefault={changePassword} method="post" class="mt-5 flex flex-col gap-5">
<div class="flex flex-col gap-2">
<label class="immich-form-label" for="password">New Password</label>
<label class="immich-form-label" for="password">{$t('new_password')}</label>
<PasswordField id="password" bind:password autocomplete="new-password" />
</div>
<div class="flex flex-col gap-2">
<label class="immich-form-label" for="confirmPassword">Confirm Password</label>
<label class="immich-form-label" for="confirmPassword">{$t('confirm_password')}</label>
<PasswordField id="confirmPassword" bind:password={passwordConfirm} autocomplete="new-password" />
</div>
@ -56,6 +57,6 @@
<p class="text-sm text-immich-primary">{success}</p>
{/if}
<div class="my-5 flex w-full">
<Button type="submit" size="lg" fullwidth>Change password</Button>
<Button type="submit" size="lg" fullwidth>{$t('change_password')}</Button>
</div>
</form>

View file

@ -9,6 +9,7 @@
import Slider from '../elements/slider.svelte';
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
import { featureFlags } from '$lib/stores/server-config.store';
import { t } from 'svelte-i18n';
export let onClose: () => void;
@ -31,7 +32,7 @@
$: {
if (password !== confirmPassword && confirmPassword.length > 0) {
error = 'Password does not match';
error = $t('password_does_not_match');
canCreateUser = false;
} else {
error = '';
@ -60,13 +61,13 @@
},
});
success = 'New user created';
success = $t('new_user_created');
dispatch('submit');
return;
} catch (error) {
handleError(error, 'Unable to create user');
handleError(error, $t('errors.unable_to_create_user'));
} finally {
isCreatingUser = false;
}
@ -74,10 +75,10 @@
}
</script>
<FullScreenModal title="Create new user" showLogo {onClose}>
<FullScreenModal title={$t('create_new_user')} showLogo {onClose}>
<form on:submit|preventDefault={registerUser} autocomplete="off" id="create-new-user-form">
<div class="my-4 flex flex-col gap-2">
<label class="immich-form-label" for="email">Email</label>
<label class="immich-form-label" for="email">{$t('email')}</label>
<input class="immich-form-input" id="email" bind:value={email} type="email" required />
</div>
@ -89,12 +90,12 @@
{/if}
<div class="my-4 flex flex-col gap-2">
<label class="immich-form-label" for="password">Password</label>
<label class="immich-form-label" for="password">{$t('password')}</label>
<PasswordField id="password" bind:password autocomplete="new-password" />
</div>
<div class="my-4 flex flex-col gap-2">
<label class="immich-form-label" for="confirmPassword">Confirm Password</label>
<label class="immich-form-label" for="confirmPassword">{$t('confirm_password')}</label>
<PasswordField id="confirmPassword" bind:password={confirmPassword} autocomplete="new-password" />
</div>
@ -106,7 +107,7 @@
</div>
<div class="my-4 flex flex-col gap-2">
<label class="immich-form-label" for="name">Name</label>
<label class="immich-form-label" for="name">{$t('name')}</label>
<input class="immich-form-input" id="name" bind:value={name} type="text" required />
</div>
@ -129,7 +130,7 @@
{/if}
</form>
<svelte:fragment slot="sticky-bottom">
<Button color="gray" fullwidth on:click={() => dispatch('cancel')}>Cancel</Button>
<Button type="submit" disabled={isCreatingUser} fullwidth form="create-new-user-form">Create</Button>
<Button color="gray" fullwidth on:click={() => dispatch('cancel')}>{$t('cancel')}</Button>
<Button type="submit" disabled={isCreatingUser} fullwidth form="create-new-user-form">{$t('create')}</Button>
</svelte:fragment>
</FullScreenModal>

View file

@ -4,6 +4,7 @@
import Button from '$lib/components/elements/buttons/button.svelte';
import AlbumCover from '$lib/components/album-page/album-cover.svelte';
import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
import { t } from 'svelte-i18n';
export let album: AlbumResponseDto;
export let onEditSuccess: ((album: AlbumResponseDto) => unknown) | undefined = undefined;
@ -36,7 +37,7 @@
};
</script>
<FullScreenModal title="Edit album" width="wide" {onClose}>
<FullScreenModal title={$t('edit_album')} width="wide" {onClose}>
<form on:submit|preventDefault={handleUpdateAlbumInfo} autocomplete="off" id="edit-album-form">
<div class="flex items-center">
<div class="hidden sm:flex">
@ -45,19 +46,19 @@
<div class="flex-grow">
<div class="m-4 flex flex-col gap-2">
<label class="immich-form-label" for="name">Name</label>
<label class="immich-form-label" for="name">{$t('name')}</label>
<input class="immich-form-input" id="name" type="text" bind:value={albumName} />
</div>
<div class="m-4 flex flex-col gap-2">
<label class="immich-form-label" for="description">Description</label>
<label class="immich-form-label" for="description">{$t('description')}</label>
<textarea class="immich-form-input" id="description" bind:value={description} />
</div>
</div>
</div>
</form>
<svelte:fragment slot="sticky-bottom">
<Button color="gray" fullwidth on:click={() => onCancel?.()}>Cancel</Button>
<Button type="submit" fullwidth disabled={isSubmitting} form="edit-album-form">OK</Button>
<Button color="gray" fullwidth on:click={() => onCancel?.()}>{$t('cancel')}</Button>
<Button type="submit" fullwidth disabled={isSubmitting} form="edit-album-form">{$t('ok')}</Button>
</svelte:fragment>
</FullScreenModal>

View file

@ -9,6 +9,7 @@
import { createEventDispatcher } from 'svelte';
import Button from '../elements/buttons/button.svelte';
import { dialogController } from '$lib/components/shared-components/dialog/dialog';
import { t } from 'svelte-i18n';
export let user: UserAdminResponseDto;
export let canResetPassword = true;
@ -47,7 +48,7 @@
dispatch('editSuccess');
} catch (error) {
handleError(error, 'Unable to update user');
handleError(error, $t('errors.unable_to_update_user'));
}
};
@ -74,7 +75,7 @@
dispatch('resetPasswordSuccess');
} catch (error) {
handleError(error, 'Unable to reset password');
handleError(error, $t('errors.unable_to_reset_password'));
}
};
@ -96,15 +97,15 @@
}
</script>
<FullScreenModal title="Edit user" icon={mdiAccountEditOutline} {onClose}>
<FullScreenModal title={$t('edit_user')} icon={mdiAccountEditOutline} {onClose}>
<form on:submit|preventDefault={editUser} autocomplete="off" id="edit-user-form">
<div class="my-4 flex flex-col gap-2">
<label class="immich-form-label" for="email">Email</label>
<label class="immich-form-label" for="email">{$t('email')}</label>
<input class="immich-form-input" id="email" name="email" type="email" bind:value={user.email} />
</div>
<div class="my-4 flex flex-col gap-2">
<label class="immich-form-label" for="name">Name</label>
<label class="immich-form-label" for="name">{$t('name')}</label>
<input class="immich-form-input" id="name" name="name" type="text" required bind:value={user.name} />
</div>
@ -119,7 +120,7 @@
</div>
<div class="my-4 flex flex-col gap-2">
<label class="immich-form-label" for="storage-label">Storage Label</label>
<label class="immich-form-label" for="storage-label">{$t('storage_label')}</label>
<input
class="immich-form-input"
id="storage-label"
@ -146,8 +147,8 @@
</form>
<svelte:fragment slot="sticky-bottom">
{#if canResetPassword}
<Button color="light-red" fullwidth on:click={resetPassword}>Reset password</Button>
<Button color="light-red" fullwidth on:click={resetPassword}>{$t('reset_password')}</Button>
{/if}
<Button type="submit" fullwidth form="edit-user-form">Confirm</Button>
<Button type="submit" fullwidth form="edit-user-form">{$t('confirm')}</Button>
</svelte:fragment>
</FullScreenModal>

View file

@ -4,11 +4,12 @@
import FullScreenModal from '../shared-components/full-screen-modal.svelte';
import { mdiFolderRemove } from '@mdi/js';
import { onMount } from 'svelte';
import { t } from 'svelte-i18n';
export let exclusionPattern: string;
export let exclusionPatterns: string[] = [];
export let isEditing = false;
export let submitText = 'Submit';
export let submitText = $t('submit');
onMount(() => {
if (isEditing) {
@ -28,7 +29,7 @@
const handleSubmit = () => dispatch('submit', { excludePattern: exclusionPattern });
</script>
<FullScreenModal title="Add exclusion pattern" icon={mdiFolderRemove} onClose={handleCancel}>
<FullScreenModal title={$t('add_exclusion_pattern')} icon={mdiFolderRemove} onClose={handleCancel}>
<form on:submit|preventDefault={() => handleSubmit()} autocomplete="off" id="add-exclusion-pattern-form">
<p class="py-5 text-sm">
Exclusion patterns lets you ignore files and folders when scanning your library. This is useful if you have
@ -38,7 +39,7 @@
use "**/Raw/**". To ignore all files ending in ".tif", use "**/*.tif". To ignore an absolute path, use "/path/to/ignore/**".
</p>
<div class="my-4 flex flex-col gap-2">
<label class="immich-form-label" for="exclusionPattern">Pattern</label>
<label class="immich-form-label" for="exclusionPattern">{$t('pattern')}</label>
<input
class="immich-form-input"
id="exclusionPattern"
@ -54,9 +55,9 @@
</div>
</form>
<svelte:fragment slot="sticky-bottom">
<Button color="gray" fullwidth on:click={() => handleCancel()}>Cancel</Button>
<Button color="gray" fullwidth on:click={() => handleCancel()}>{$t('cancel')}</Button>
{#if isEditing}
<Button color="red" fullwidth on:click={() => dispatch('delete')}>Delete</Button>
<Button color="red" fullwidth on:click={() => dispatch('delete')}>{$t('delete')}</Button>
{/if}
<Button type="submit" disabled={!canSubmit} fullwidth form="add-exclusion-pattern-form">{submitText}</Button>
</svelte:fragment>

View file

@ -4,12 +4,13 @@
import FullScreenModal from '../shared-components/full-screen-modal.svelte';
import { mdiFolderSync } from '@mdi/js';
import { onMount } from 'svelte';
import { t } from 'svelte-i18n';
export let importPath: string | null;
export let importPaths: string[] = [];
export let title = 'Import path';
export let cancelText = 'Cancel';
export let submitText = 'Save';
export let title = $t('import_path');
export let cancelText = $t('cancel');
export let submitText = $t('save');
export let isEditing = false;
onMount(() => {
@ -37,7 +38,7 @@
</p>
<div class="my-4 flex flex-col gap-2">
<label class="immich-form-label" for="path">Path</label>
<label class="immich-form-label" for="path">{$t('path')}</label>
<input class="immich-form-input" id="path" name="path" type="text" bind:value={importPath} />
</div>
@ -50,7 +51,7 @@
<svelte:fragment slot="sticky-bottom">
<Button color="gray" fullwidth on:click={() => handleCancel()}>{cancelText}</Button>
{#if isEditing}
<Button color="red" fullwidth on:click={() => dispatch('delete')}>Delete</Button>
<Button color="red" fullwidth on:click={() => dispatch('delete')}>{$t('delete')}</Button>
{/if}
<Button type="submit" disabled={!canSubmit} fullwidth form="library-import-path-form">{submitText}</Button>
</svelte:fragment>

View file

@ -10,6 +10,7 @@
import { NotificationType, notificationController } from '../shared-components/notification/notification';
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
import { s } from '$lib/utils';
import { t } from 'svelte-i18n';
export let library: LibraryResponseDto;
@ -149,8 +150,8 @@
{#if addImportPath}
<LibraryImportPathForm
title="Add import path"
submitText="Add"
title={$t('add_import_path')}
submitText={$t('add')}
bind:importPath={importPathToAdd}
{importPaths}
on:submit={handleAddImportPath}
@ -163,8 +164,8 @@
{#if editImportPath != undefined}
<LibraryImportPathForm
title="Edit import path"
submitText="Save"
title={$t('edit_import_path')}
submitText={$t('save')}
isEditing={true}
bind:importPath={editedImportPath}
{importPaths}
@ -210,7 +211,7 @@
<CircleIconButton
color="primary"
icon={mdiPencilOutline}
title="Edit import path"
title={$t('edit_import_path')}
size="16"
on:click={() => {
editImportPath = listIndex;
@ -238,7 +239,7 @@
size="sm"
on:click={() => {
addImportPath = true;
}}>Add path</Button
}}>{$t('add_path')}</Button
></td
>
</tr>
@ -246,11 +247,13 @@
</table>
<div class="flex justify-between w-full">
<div class="justify-end gap-2">
<Button size="sm" color="gray" on:click={() => revalidate()}><Icon path={mdiRefresh} size={20} />Validate</Button>
<Button size="sm" color="gray" on:click={() => revalidate()}
><Icon path={mdiRefresh} size={20} />{$t('validate')}</Button
>
</div>
<div class="justify-end gap-2">
<Button size="sm" color="gray" on:click={() => handleCancel()}>Cancel</Button>
<Button size="sm" type="submit">Save</Button>
<Button size="sm" color="gray" on:click={() => handleCancel()}>{$t('cancel')}</Button>
<Button size="sm" type="submit">{$t('save')}</Button>
</div>
</div>
</form>

View file

@ -2,6 +2,7 @@
import type { LibraryResponseDto } from '@immich/sdk';
import { createEventDispatcher } from 'svelte';
import Button from '../elements/buttons/button.svelte';
import { t } from 'svelte-i18n';
export let library: Partial<LibraryResponseDto>;
@ -20,11 +21,11 @@
<form on:submit|preventDefault={() => handleSubmit()} autocomplete="off" class="m-4 flex flex-col gap-2">
<div class="flex flex-col gap-2">
<label class="immich-form-label" for="path">Name</label>
<label class="immich-form-label" for="path">{$t('name')}</label>
<input class="immich-form-input" id="name" name="name" type="text" bind:value={library.name} />
</div>
<div class="flex w-full justify-end gap-2 pt-2">
<Button size="sm" color="gray" on:click={() => handleCancel()}>Cancel</Button>
<Button size="sm" type="submit">Save</Button>
<Button size="sm" color="gray" on:click={() => handleCancel()}>{$t('cancel')}</Button>
<Button size="sm" type="submit">{$t('save')}</Button>
</div>
</form>

View file

@ -6,6 +6,7 @@
import Button from '../elements/buttons/button.svelte';
import LibraryExclusionPatternForm from './library-exclusion-pattern-form.svelte';
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
import { t } from 'svelte-i18n';
export let library: Partial<LibraryResponseDto>;
@ -102,7 +103,7 @@
{#if addExclusionPattern}
<LibraryExclusionPatternForm
submitText="Add"
submitText={$t('add')}
bind:exclusionPattern={exclusionPatternToAdd}
{exclusionPatterns}
on:submit={handleAddExclusionPattern}
@ -114,7 +115,7 @@
{#if editExclusionPattern != undefined}
<LibraryExclusionPatternForm
submitText="Save"
submitText={$t('save')}
isEditing={true}
bind:exclusionPattern={editedExclusionPattern}
{exclusionPatterns}
@ -142,7 +143,7 @@
<CircleIconButton
color="primary"
icon={mdiPencilOutline}
title="Edit exclusion pattern"
title={$t('edit_exclusion_pattern')}
size="16"
on:click={() => {
editExclusionPattern = listIndex;
@ -169,7 +170,7 @@
size="sm"
on:click={() => {
addExclusionPattern = true;
}}>Add exclusion pattern</Button
}}>{$t('add_exclusion_pattern')}</Button
></td
></tr
>
@ -177,7 +178,7 @@
</table>
<div class="flex w-full justify-end gap-4">
<Button size="sm" color="gray" on:click={() => handleCancel()}>Cancel</Button>
<Button size="sm" type="submit">Save</Button>
<Button size="sm" color="gray" on:click={() => handleCancel()}>{$t('cancel')}</Button>
<Button size="sm" type="submit">{$t('save')}</Button>
</div>
</form>

View file

@ -7,6 +7,7 @@
import { searchUsersAdmin } from '@immich/sdk';
import { user } from '$lib/stores/user.store';
import SettingSelect from '$lib/components/shared-components/settings/setting-select.svelte';
import { t } from 'svelte-i18n';
let ownerId: string = $user.id;
@ -27,14 +28,14 @@
const handleSubmit = () => dispatch('submit', { ownerId });
</script>
<FullScreenModal title="Select library owner" icon={mdiFolderSync} onClose={handleCancel}>
<FullScreenModal title={$t('select_library_owner')} icon={mdiFolderSync} onClose={handleCancel}>
<form on:submit|preventDefault={() => handleSubmit()} autocomplete="off" id="select-library-owner-form">
<p class="p-5 text-sm">NOTE: This cannot be changed later!</p>
<SettingSelect bind:value={ownerId} options={userOptions} name="user" />
</form>
<svelte:fragment slot="sticky-bottom">
<Button color="gray" fullwidth on:click={() => handleCancel()}>Cancel</Button>
<Button type="submit" fullwidth form="select-library-owner-form">Create</Button>
<Button color="gray" fullwidth on:click={() => handleCancel()}>{$t('cancel')}</Button>
<Button type="submit" fullwidth form="select-library-owner-form">{$t('create')}</Button>
</svelte:fragment>
</FullScreenModal>

View file

@ -10,6 +10,7 @@
import { fade } from 'svelte/transition';
import Button from '../elements/buttons/button.svelte';
import PasswordField from '../shared-components/password-field.svelte';
import { t } from 'svelte-i18n';
export let onSuccess: () => unknown | Promise<unknown>;
export let onFirstLogin: () => unknown | Promise<unknown>;
@ -99,7 +100,7 @@
{/if}
<div class="flex flex-col gap-2">
<label class="immich-form-label" for="email">Email</label>
<label class="immich-form-label" for="email">{$t('email')}</label>
<input
class="immich-form-input"
id="email"
@ -112,7 +113,7 @@
</div>
<div class="flex flex-col gap-2">
<label class="immich-form-label" for="password">Password</label>
<label class="immich-form-label" for="password">{$t('password')}</label>
<PasswordField id="password" bind:password autocomplete="current-password" />
</div>
@ -165,5 +166,5 @@
{/if}
{#if !$featureFlags.passwordLogin && !$featureFlags.oauth}
<p class="p-4 text-center dark:text-immich-dark-fg">Login has been disabled.</p>
<p class="p-4 text-center dark:text-immich-dark-fg">{$t('login_has_been_disabled')}</p>
{/if}