mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
chore(web): more translations for user settings and admin pages (#10161)
* chore(web): more translations for user settings and admin pages * JobSettings translations * feedback * missed one * feedback
This commit is contained in:
parent
0e1311e3d3
commit
9e5c52b7b7
34 changed files with 300 additions and 160 deletions
|
|
@ -84,7 +84,9 @@
|
|||
|
||||
{#if $featureFlags.email}
|
||||
<div class="my-4 flex place-items-center justify-between gap-2">
|
||||
<label class="text-sm dark:text-immich-dark-fg" for="send-welcome-email"> Send welcome email </label>
|
||||
<label class="text-sm dark:text-immich-dark-fg" for="send-welcome-email">
|
||||
{$t('admin.send_welcome_email')}
|
||||
</label>
|
||||
<Slider id="send-welcome-email" bind:checked={notify} />
|
||||
</div>
|
||||
{/if}
|
||||
|
|
@ -101,7 +103,7 @@
|
|||
|
||||
<div class="my-4 flex place-items-center justify-between gap-2">
|
||||
<label class="text-sm dark:text-immich-dark-fg" for="require-password-change">
|
||||
Require user to change password on first login
|
||||
{$t('admin.require_password_change_on_login')}
|
||||
</label>
|
||||
<Slider id="require-password-change" bind:checked={shouldChangePassword} />
|
||||
</div>
|
||||
|
|
@ -113,9 +115,9 @@
|
|||
|
||||
<div class="my-4 flex flex-col gap-2">
|
||||
<label class="flex items-center gap-2 immich-form-label" for="quotaSize">
|
||||
Quota Size (GiB)
|
||||
{$t('admin.quota_size_gib')}
|
||||
{#if quotaSizeWarning}
|
||||
<p class="text-red-400 text-sm">You set a quota higher than the disk size</p>
|
||||
<p class="text-red-400 text-sm">{$t('admin.quota_higher_than_disk_size')}</p>
|
||||
{/if}
|
||||
</label>
|
||||
<input class="immich-form-input" id="quotaSize" type="number" min="0" bind:value={quotaSize} />
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@
|
|||
const resetPassword = async () => {
|
||||
const isConfirmed = await dialogController.show({
|
||||
id: 'confirm-reset-password',
|
||||
prompt: `Are you sure you want to reset ${user.name}'s password?`,
|
||||
prompt: $t('admin.confirm_user_password_reset', { values: { user: user.name } }),
|
||||
});
|
||||
|
||||
if (!isConfirmed) {
|
||||
|
|
@ -110,13 +110,14 @@
|
|||
</div>
|
||||
|
||||
<div class="my-4 flex flex-col gap-2">
|
||||
<label class="flex items-center gap-2 immich-form-label" for="quotaSize"
|
||||
>Quota Size (GiB) {#if quotaSizeWarning}
|
||||
<p class="text-red-400 text-sm">You set a quota higher than the disk size</p>
|
||||
<label class="flex items-center gap-2 immich-form-label" for="quotaSize">
|
||||
{$t('admin.quota_size_gib')}
|
||||
{#if quotaSizeWarning}
|
||||
<p class="text-red-400 text-sm">{$t('errors.quota_higher_than_disk_size')}</p>
|
||||
{/if}</label
|
||||
>
|
||||
<input class="immich-form-input" id="quotaSize" name="quotaSize" type="number" min="0" bind:value={quotaSize} />
|
||||
<p>Note: Enter 0 for unlimited quota</p>
|
||||
<p>{$t('admin.note_unlimited_quota')}</p>
|
||||
</div>
|
||||
|
||||
<div class="my-4 flex flex-col gap-2">
|
||||
|
|
@ -130,10 +131,10 @@
|
|||
/>
|
||||
|
||||
<p>
|
||||
Note: To apply the Storage Label to previously uploaded assets, run the
|
||||
{$t('admin.note_apply_storage_label_previous_assets')}
|
||||
<a href={AppRoute.ADMIN_JOBS} class="text-immich-primary dark:text-immich-dark-primary">
|
||||
Storage Migration Job</a
|
||||
>
|
||||
{$t('admin.storage_template_migration_job')}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -32,11 +32,9 @@
|
|||
<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
|
||||
folders that contain files you don't want to import, such as RAW files.
|
||||
{$t('admin.exclusion_pattern_description')}
|
||||
<br /><br />
|
||||
Add exclusion patterns. Globbing using *, **, and ? is supported. To ignore all files in any directory named "Raw",
|
||||
use "**/Raw/**". To ignore all files ending in ".tif", use "**/*.tif". To ignore an absolute path, use "/path/to/ignore/**".
|
||||
{$t('admin.add_exclusion_pattern_description')}
|
||||
</p>
|
||||
<div class="my-4 flex flex-col gap-2">
|
||||
<label class="immich-form-label" for="exclusionPattern">{$t('pattern')}</label>
|
||||
|
|
@ -50,7 +48,7 @@
|
|||
</div>
|
||||
<div class="mt-8 flex w-full gap-4">
|
||||
{#if isDuplicate}
|
||||
<p class="text-red-500 text-sm">This exclusion pattern already exists.</p>
|
||||
<p class="text-red-500 text-sm">{$t('errors.exclusion_pattern_already_exists')}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -33,9 +33,7 @@
|
|||
|
||||
<FullScreenModal {title} icon={mdiFolderSync} onClose={handleCancel}>
|
||||
<form on:submit|preventDefault={() => handleSubmit()} autocomplete="off" id="library-import-path-form">
|
||||
<p class="py-5 text-sm">
|
||||
Specify a folder to import. This folder, including subfolders, will be scanned for images and videos.
|
||||
</p>
|
||||
<p class="py-5 text-sm">{$t('admin.library_import_path_description')}</p>
|
||||
|
||||
<div class="my-4 flex flex-col gap-2">
|
||||
<label class="immich-form-label" for="path">{$t('path')}</label>
|
||||
|
|
@ -44,7 +42,7 @@
|
|||
|
||||
<div class="mt-8 flex w-full gap-4">
|
||||
{#if isDuplicate}
|
||||
<p class="text-red-500 text-sm">This import path already exists.</p>
|
||||
<p class="text-red-500 text-sm">{$t('admin.import_path_already_exists')}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
import type { ValidateLibraryImportPathResponseDto } from '@immich/sdk';
|
||||
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;
|
||||
|
|
@ -54,13 +53,13 @@
|
|||
if (failedPaths === 0) {
|
||||
if (notifyIfSuccessful) {
|
||||
notificationController.show({
|
||||
message: `All paths validated successfully`,
|
||||
message: $t('admin.paths_validated_successfully'),
|
||||
type: NotificationType.Info,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
notificationController.show({
|
||||
message: `${failedPaths} path${s(failedPaths)} failed validation`,
|
||||
message: $t('errors.paths_validation_failed', { values: { paths: failedPaths } }),
|
||||
type: NotificationType.Warning,
|
||||
});
|
||||
}
|
||||
|
|
@ -95,7 +94,7 @@
|
|||
await revalidate(false);
|
||||
}
|
||||
} catch (error) {
|
||||
handleError(error, 'Unable to add import path');
|
||||
handleError(error, $t('errors.unable_to_add_import_path'));
|
||||
} finally {
|
||||
addImportPath = false;
|
||||
importPathToAdd = null;
|
||||
|
|
@ -121,7 +120,7 @@
|
|||
}
|
||||
} catch (error) {
|
||||
editImportPath = null;
|
||||
handleError(error, 'Unable to edit import path');
|
||||
handleError(error, $t('errors.unable_to_edit_import_path'));
|
||||
} finally {
|
||||
editImportPath = null;
|
||||
}
|
||||
|
|
@ -141,7 +140,7 @@
|
|||
library.importPaths = library.importPaths.filter((path) => path != pathToDelete);
|
||||
await handleValidation();
|
||||
} catch (error) {
|
||||
handleError(error, 'Unable to delete import path');
|
||||
handleError(error, $t('errors.unable_to_delete_import_path'));
|
||||
} finally {
|
||||
editImportPath = null;
|
||||
}
|
||||
|
|
@ -230,7 +229,7 @@
|
|||
>
|
||||
<td class="w-4/5 text-ellipsis px-4 text-sm">
|
||||
{#if importPaths.length === 0}
|
||||
No paths added
|
||||
{$t('admin.no_paths_added')}
|
||||
{/if}</td
|
||||
>
|
||||
<td class="w-1/5 text-ellipsis px-4 text-sm"
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
exclusionPatterns = library.exclusionPatterns;
|
||||
}
|
||||
} catch (error) {
|
||||
handleError(error, 'Unable to add exclusion pattern');
|
||||
handleError(error, $t('errors.unable_to_add_exclusion_pattern'));
|
||||
} finally {
|
||||
exclusionPatternToAdd = '';
|
||||
addExclusionPattern = false;
|
||||
|
|
@ -74,7 +74,7 @@
|
|||
library.exclusionPatterns[editExclusionPattern] = editedExclusionPattern;
|
||||
exclusionPatterns = library.exclusionPatterns;
|
||||
} catch (error) {
|
||||
handleError(error, 'Unable to edit exclude pattern');
|
||||
handleError(error, $t('errors.unable_to_edit_exclusion_pattern'));
|
||||
} finally {
|
||||
editExclusionPattern = null;
|
||||
}
|
||||
|
|
@ -94,7 +94,7 @@
|
|||
library.exclusionPatterns = library.exclusionPatterns.filter((path) => path != pathToDelete);
|
||||
exclusionPatterns = library.exclusionPatterns;
|
||||
} catch (error) {
|
||||
handleError(error, 'Unable to delete exclude pattern');
|
||||
handleError(error, $t('errors.unable_to_delete_exclusion_pattern'));
|
||||
} finally {
|
||||
editExclusionPattern = null;
|
||||
}
|
||||
|
|
@ -162,7 +162,7 @@
|
|||
>
|
||||
<td class="w-3/4 text-ellipsis px-4 text-sm">
|
||||
{#if exclusionPatterns.length === 0}
|
||||
No pattern added
|
||||
{$t('admin.no_pattern_added')}
|
||||
{/if}
|
||||
</td>
|
||||
<td class="w-1/4 text-ellipsis px-4 text-sm"
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
<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>
|
||||
<p class="p-5 text-sm">{$t('admin.note_cannot_be_changed_later')}</p>
|
||||
|
||||
<SettingSelect bind:value={ownerId} options={userOptions} name="user" />
|
||||
</form>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue