mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
feat(web): add an option to change the date formats (#7174)
* feat: add an option to change the date formats * pr feedback * fix: change title * fix: show list supported by the browser * fix: tests * fix: dates * fix: check only if locale is set * fix: better fallback value * fix: fallback * fix: fallback * feat: add default locale option * refactor: shared components * refactor: shared components * prepare for svelte 5 * don't use relative paths * refactor: fallback value Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> * fix: parsing store * fix: lint * refactor: locales --------- Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com> Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
parent
a224bb23d0
commit
01d6707b59
45 changed files with 383 additions and 80 deletions
|
|
@ -14,12 +14,14 @@
|
|||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import SettingAccordion from '../setting-accordion.svelte';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingCheckboxes from '../setting-checkboxes.svelte';
|
||||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import SettingSelect from '../setting-select.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.svelte';
|
||||
import SettingInputField, {
|
||||
SettingInputFieldType,
|
||||
} from '$lib/components/shared-components/settings/setting-input-field.svelte';
|
||||
import SettingSelect from '$lib/components/shared-components/settings/setting-select.svelte';
|
||||
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
|
||||
import SettingCheckboxes from '$lib/components/shared-components/settings/setting-checkboxes.svelte';
|
||||
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@
|
|||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
|
||||
import SettingInputField, {
|
||||
SettingInputFieldType,
|
||||
} from '$lib/components/shared-components/settings/setting-input-field.svelte';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@
|
|||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import SettingAccordion from '../setting-accordion.svelte';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.svelte';
|
||||
import SettingInputField, {
|
||||
SettingInputFieldType,
|
||||
} 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';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingSelect from '../setting-select.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
|
||||
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
|
||||
import SettingSelect from '$lib/components/shared-components/settings/setting-select.svelte';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
|
|
|||
|
|
@ -4,11 +4,13 @@
|
|||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import SettingAccordion from '../setting-accordion.svelte';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import SettingSelect from '../setting-select.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.svelte';
|
||||
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
|
||||
import SettingInputField, {
|
||||
SettingInputFieldType,
|
||||
} from '$lib/components/shared-components/settings/setting-input-field.svelte';
|
||||
import SettingSelect from '$lib/components/shared-components/settings/setting-select.svelte';
|
||||
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@
|
|||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import SettingAccordion from '../setting-accordion.svelte';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.svelte';
|
||||
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
|
||||
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
|
||||
import SettingInputField, {
|
||||
SettingInputFieldType,
|
||||
} from '$lib/components/shared-components/settings/setting-input-field.svelte';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
|
||||
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@
|
|||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import ConfirmDisableLogin from '../confirm-disable-login.svelte';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
|
||||
import SettingInputField, {
|
||||
SettingInputFieldType,
|
||||
} from '$lib/components/shared-components/settings/setting-input-field.svelte';
|
||||
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import ConfirmDisableLogin from '../confirm-disable-login.svelte';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
|
||||
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
<script lang="ts">
|
||||
import SettingButtonsRow from '$lib/components/admin-page/settings/setting-buttons-row.svelte';
|
||||
import type { SystemConfigDto } from '@immich/sdk';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import SettingInputField, {
|
||||
SettingInputFieldType,
|
||||
} from '$lib/components/shared-components/settings/setting-input-field.svelte';
|
||||
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
|
|
|||
|
|
@ -1,71 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { QueryParameter } from '$lib/constants';
|
||||
import { hasParamValue, updateParamList } from '$lib/utils';
|
||||
import { slide } from 'svelte/transition';
|
||||
|
||||
export let title: string;
|
||||
export let subtitle = '';
|
||||
export let key: string;
|
||||
export let isOpen = false;
|
||||
|
||||
const syncFromUrl = () => (isOpen = hasParamValue(QueryParameter.IS_OPEN, key));
|
||||
const syncToUrl = (isOpen: boolean) => updateParamList({ param: QueryParameter.IS_OPEN, value: key, add: isOpen });
|
||||
|
||||
isOpen ? syncToUrl(true) : syncFromUrl();
|
||||
$: $page.url && syncFromUrl();
|
||||
|
||||
const toggle = () => {
|
||||
isOpen = !isOpen;
|
||||
syncToUrl(isOpen);
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="border-b-[1px] border-gray-200 py-4 dark:border-gray-700">
|
||||
<button on:click={toggle} class="flex w-full place-items-center justify-between text-left">
|
||||
<div>
|
||||
<h2 class="font-medium text-immich-primary dark:text-immich-dark-primary">
|
||||
{title}
|
||||
</h2>
|
||||
|
||||
<slot name="subtitle">
|
||||
<p class="text-sm dark:text-immich-dark-fg">{subtitle}</p>
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
<button
|
||||
aria-expanded={isOpen}
|
||||
class="immich-circle-icon-button flex place-content-center place-items-center rounded-full p-3 transition-all hover:bg-immich-primary/10 dark:text-immich-dark-fg hover:dark:bg-immich-dark-primary/20"
|
||||
>
|
||||
<svg
|
||||
style="tran"
|
||||
width="20"
|
||||
height="20"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
</button>
|
||||
|
||||
{#if isOpen}
|
||||
<ul transition:slide={{ duration: 250 }} class="mb-2 ml-4">
|
||||
<slot />
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
svg {
|
||||
transition: transform 0.2s ease-in;
|
||||
}
|
||||
|
||||
[aria-expanded='true'] svg {
|
||||
transform: rotate(0.5turn);
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<script lang="ts">
|
||||
import Button from '$lib/components/elements/buttons/button.svelte';
|
||||
import type { ResetOptions } from '$lib/utils/dipatch';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
reset: ResetOptions;
|
||||
save: void;
|
||||
}>();
|
||||
|
||||
export let showResetToDefault = true;
|
||||
export let disabled = false;
|
||||
</script>
|
||||
|
||||
<div class="mt-8 flex justify-between gap-2">
|
||||
<div class="left">
|
||||
{#if showResetToDefault}
|
||||
<button
|
||||
on:click={() => dispatch('reset', { default: true })}
|
||||
class="bg-none text-sm font-medium text-immich-primary hover:text-immich-primary/75 dark:text-immich-dark-primary hover:dark:text-immich-dark-primary/75"
|
||||
>
|
||||
Reset to default
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<Button {disabled} size="sm" color="gray" on:click={() => dispatch('reset', { default: false })}>Reset</Button>
|
||||
<Button {disabled} size="sm" on:click={() => dispatch('save')}>Save</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { quintOut } from 'svelte/easing';
|
||||
import { fly } from 'svelte/transition';
|
||||
|
||||
export let value: string[];
|
||||
export let options: { value: string; text: string }[];
|
||||
export let label = '';
|
||||
export let desc = '';
|
||||
export let name = '';
|
||||
export let isEdited = false;
|
||||
export let disabled = false;
|
||||
|
||||
function handleCheckboxChange(option: string) {
|
||||
value = value.includes(option) ? value.filter((item) => item !== option) : [...value, option];
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="mb-4 w-full">
|
||||
<div class={`flex h-[26px] place-items-center gap-1`}>
|
||||
<label class={`immich-form-label text-sm`} for="{name}-select">{label}</label>
|
||||
|
||||
{#if isEdited}
|
||||
<div
|
||||
transition:fly={{ x: 10, duration: 200, easing: quintOut }}
|
||||
class="rounded-full bg-orange-100 px-2 text-[10px] text-orange-900"
|
||||
>
|
||||
Unsaved change
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if desc}
|
||||
<p class="immich-form-label pb-2 text-sm" id="{name}-desc">
|
||||
{desc}
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
{#each options as option}
|
||||
<label class="flex items-center mb-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="form-checkbox h-5 w-5 color"
|
||||
{disabled}
|
||||
checked={value.includes(option.value)}
|
||||
on:change={() => handleCheckboxChange(option.value)}
|
||||
/>
|
||||
<span class="ml-2 text-sm text-gray-500 dark:text-gray-300 pt-1">{option.text}</span>
|
||||
</label>
|
||||
{/each}
|
||||
</div>
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
<script lang="ts" context="module">
|
||||
export enum SettingInputFieldType {
|
||||
EMAIL = 'email',
|
||||
TEXT = 'text',
|
||||
NUMBER = 'number',
|
||||
PASSWORD = 'password',
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { quintOut } from 'svelte/easing';
|
||||
import { fly } from 'svelte/transition';
|
||||
|
||||
export let inputType: SettingInputFieldType;
|
||||
export let value: string | number;
|
||||
export let min = Number.MIN_SAFE_INTEGER.toString();
|
||||
export let max = Number.MAX_SAFE_INTEGER.toString();
|
||||
export let step = '1';
|
||||
export let label = '';
|
||||
export let desc = '';
|
||||
export let title = '';
|
||||
export let required = false;
|
||||
export let disabled = false;
|
||||
export let isEdited = false;
|
||||
|
||||
const handleInput = (e: Event) => {
|
||||
value = (e.target as HTMLInputElement).value;
|
||||
if (inputType === SettingInputFieldType.NUMBER) {
|
||||
value = Number(value) || 0;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="mb-4 w-full">
|
||||
<div class={`flex h-[26px] place-items-center gap-1`}>
|
||||
<label class={`immich-form-label text-sm`} for={label}>{label}</label>
|
||||
{#if required}
|
||||
<div class="text-red-400">*</div>
|
||||
{/if}
|
||||
|
||||
{#if isEdited}
|
||||
<div
|
||||
transition:fly={{ x: 10, duration: 200, easing: quintOut }}
|
||||
class="rounded-full bg-orange-100 px-2 text-[10px] text-orange-900"
|
||||
>
|
||||
Unsaved change
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if desc}
|
||||
<p class="immich-form-label pb-2 text-sm" id="{label}-desc">
|
||||
{desc}
|
||||
</p>
|
||||
{:else}
|
||||
<slot name="desc" />
|
||||
{/if}
|
||||
|
||||
<input
|
||||
class="immich-form-input w-full pb-2"
|
||||
aria-describedby={desc ? `${label}-desc` : undefined}
|
||||
aria-labelledby="{label}-label"
|
||||
id={label}
|
||||
name={label}
|
||||
type={inputType}
|
||||
{min}
|
||||
{max}
|
||||
{step}
|
||||
{required}
|
||||
{value}
|
||||
on:input={handleInput}
|
||||
{disabled}
|
||||
{title}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { quintOut } from 'svelte/easing';
|
||||
import { fly } from 'svelte/transition';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
export let value: string | number;
|
||||
export let options: { value: string | number; text: string }[];
|
||||
export let label = '';
|
||||
export let desc = '';
|
||||
export let name = '';
|
||||
export let isEdited = false;
|
||||
export let number = false;
|
||||
export let disabled = false;
|
||||
|
||||
const dispatch = createEventDispatcher<{ select: string | number }>();
|
||||
|
||||
const handleChange = (e: Event) => {
|
||||
value = (e.target as HTMLInputElement).value;
|
||||
if (number) {
|
||||
value = Number.parseInt(value);
|
||||
}
|
||||
dispatch('select', value);
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="mb-4 w-full">
|
||||
<div class={`flex h-[26px] place-items-center gap-1`}>
|
||||
<label class={`immich-form-label text-sm`} for="{name}-select">{label}</label>
|
||||
|
||||
{#if isEdited}
|
||||
<div
|
||||
transition:fly={{ x: 10, duration: 200, easing: quintOut }}
|
||||
class="rounded-full bg-orange-100 px-2 text-[10px] text-orange-900"
|
||||
>
|
||||
Unsaved change
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if desc}
|
||||
<p class="immich-form-label pb-2 text-sm" id="{name}-desc">
|
||||
{desc}
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
<select
|
||||
class="immich-form-input w-full pb-2"
|
||||
{disabled}
|
||||
aria-describedby={desc ? `${name}-desc` : undefined}
|
||||
{name}
|
||||
id="{name}-select"
|
||||
bind:value
|
||||
on:change={handleChange}
|
||||
>
|
||||
{#each options as option}
|
||||
<option value={option.value}>{option.text}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { quintOut } from 'svelte/easing';
|
||||
import { fly } from 'svelte/transition';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
export let title: string;
|
||||
export let subtitle = '';
|
||||
export let checked = false;
|
||||
export let disabled = false;
|
||||
export let isEdited = false;
|
||||
|
||||
const dispatch = createEventDispatcher<{ toggle: boolean }>();
|
||||
const onToggle = (event: Event) => dispatch('toggle', (event.target as HTMLInputElement).checked);
|
||||
</script>
|
||||
|
||||
<div class="flex place-items-center justify-between">
|
||||
<div>
|
||||
<div class="flex h-[26px] place-items-center gap-1">
|
||||
<label class="font-medium text-immich-primary dark:text-immich-dark-primary text-sm" for={title}>
|
||||
{title}
|
||||
</label>
|
||||
{#if isEdited}
|
||||
<div
|
||||
transition:fly={{ x: 10, duration: 200, easing: quintOut }}
|
||||
class="rounded-full bg-orange-100 px-2 text-[10px] text-orange-900"
|
||||
>
|
||||
Unsaved change
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<p class="text-sm dark:text-immich-dark-fg">{subtitle}</p>
|
||||
</div>
|
||||
|
||||
<label class="relative inline-block h-[10px] w-[36px] flex-none">
|
||||
<input
|
||||
class="disabled::cursor-not-allowed h-0 w-0 opacity-0"
|
||||
type="checkbox"
|
||||
bind:checked
|
||||
on:click={onToggle}
|
||||
{disabled}
|
||||
/>
|
||||
|
||||
{#if disabled}
|
||||
<span class="slider slider-disabled cursor-not-allowed" />
|
||||
{:else}
|
||||
<span class="slider slider-enabled cursor-pointer" />
|
||||
{/if}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.slider {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #ccc;
|
||||
-webkit-transition: 0.4s;
|
||||
transition: 0.4s;
|
||||
border-radius: 34px;
|
||||
}
|
||||
|
||||
input:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
bottom: -4px;
|
||||
background-color: gray;
|
||||
-webkit-transition: 0.4s;
|
||||
transition: 0.4s;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
-webkit-transform: translateX(18px);
|
||||
-ms-transform: translateX(18px);
|
||||
transform: translateX(18px);
|
||||
background-color: #4250af;
|
||||
}
|
||||
|
||||
input:checked + .slider-disabled {
|
||||
background-color: gray;
|
||||
}
|
||||
|
||||
input:checked + .slider-enabled {
|
||||
background-color: #adcbfa;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { quintOut } from 'svelte/easing';
|
||||
import { fly } from 'svelte/transition';
|
||||
|
||||
export let value: string;
|
||||
export let label = '';
|
||||
export let desc = '';
|
||||
export let required = false;
|
||||
export let disabled = false;
|
||||
export let isEdited = false;
|
||||
|
||||
const handleInput = (e: Event) => {
|
||||
value = (e.target as HTMLInputElement).value;
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="mb-4 w-full">
|
||||
<div class={`flex h-[26px] place-items-center gap-1`}>
|
||||
<label class={`immich-form-label text-sm`} for={label}>{label}</label>
|
||||
{#if required}
|
||||
<div class="text-red-400">*</div>
|
||||
{/if}
|
||||
|
||||
{#if isEdited}
|
||||
<div
|
||||
transition:fly={{ x: 10, duration: 200, easing: quintOut }}
|
||||
class="rounded-full bg-orange-100 px-2 text-[10px] text-orange-900"
|
||||
>
|
||||
Unsaved change
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if desc}
|
||||
<p class="immich-form-label pb-2 text-sm" id="{label}-desc">
|
||||
{desc}
|
||||
</p>
|
||||
{:else}
|
||||
<slot name="desc" />
|
||||
{/if}
|
||||
|
||||
<textarea
|
||||
class="immich-form-input w-full pb-2"
|
||||
aria-describedby={desc ? `${label}-desc` : undefined}
|
||||
aria-labelledby="{label}-label"
|
||||
id={label}
|
||||
name={label}
|
||||
{required}
|
||||
{value}
|
||||
on:input={handleInput}
|
||||
{disabled}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -13,11 +13,13 @@
|
|||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import SupportedDatetimePanel from './supported-datetime-panel.svelte';
|
||||
import SupportedVariablesPanel from './supported-variables-panel.svelte';
|
||||
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
|
||||
import SettingInputField, {
|
||||
SettingInputFieldType,
|
||||
} from '$lib/components/shared-components/settings/setting-input-field.svelte';
|
||||
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
<script lang="ts">
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import type { SystemConfigTemplateStorageOptionDto } from '@immich/sdk';
|
||||
import * as luxon from 'luxon';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
export let options: SystemConfigTemplateStorageOptionDto;
|
||||
|
||||
const getLuxonExample = (format: string) => {
|
||||
return luxon.DateTime.fromISO(new Date('2022-09-04T20:03:05.250').toISOString()).toFormat(format);
|
||||
return DateTime.fromISO('2022-09-04T20:03:05.250Z', { locale: $locale }).toFormat(format);
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingTextarea from '../setting-textarea.svelte';
|
||||
import SettingTextarea from '$lib/components/shared-components/settings/setting-textarea.svelte';
|
||||
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
<script lang="ts">
|
||||
import SettingButtonsRow from '$lib/components/admin-page/settings/setting-buttons-row.svelte';
|
||||
import SettingSelect from '$lib/components/admin-page/settings/setting-select.svelte';
|
||||
import { Colorspace, type SystemConfigDto } from '@immich/sdk';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import SettingSelect from '$lib/components/shared-components/settings/setting-select.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 SettingInputField, {
|
||||
SettingInputFieldType,
|
||||
} from '$lib/components/shared-components/settings/setting-input-field.svelte';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@
|
|||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
|
||||
import SettingInputField, {
|
||||
SettingInputFieldType,
|
||||
} from '$lib/components/shared-components/settings/setting-input-field.svelte';
|
||||
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue