mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
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:
parent
a2bccf23c9
commit
f446bc8caa
177 changed files with 2779 additions and 1017 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue