refactor(web): use callbacks for admin setting events (#10997)

This commit is contained in:
Michel Heusschen 2024-07-10 15:57:18 +02:00 committed by GitHub
parent 545b206076
commit 1dd1d36120
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 125 additions and 153 deletions

View File

@ -9,8 +9,8 @@
import { getConfig, getConfigDefaults, updateConfig, type SystemConfigDto } from '@immich/sdk'; import { getConfig, getConfigDefaults, updateConfig, type SystemConfigDto } from '@immich/sdk';
import { loadConfig } from '$lib/stores/server-config.store'; import { loadConfig } from '$lib/stores/server-config.store';
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
import { createEventDispatcher, onMount } from 'svelte'; import { onMount } from 'svelte';
import type { SettingsEventType } from './admin-settings'; import type { SettingsResetOptions } from './admin-settings';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
export let config: SystemConfigDto; export let config: SystemConfigDto;
@ -18,10 +18,8 @@
let savedConfig: SystemConfigDto; let savedConfig: SystemConfigDto;
let defaultConfig: SystemConfigDto; let defaultConfig: SystemConfigDto;
const dispatch = createEventDispatcher<{ save: void }>(); const handleReset = async (options: SettingsResetOptions) => {
await (options.default ? resetToDefault(options.configKeys) : reset(options.configKeys));
const handleReset = async (detail: SettingsEventType['reset']) => {
await (detail.default ? resetToDefault(detail.configKeys) : reset(detail.configKeys));
}; };
export const handleSave = async (update: Partial<SystemConfigDto>) => { export const handleSave = async (update: Partial<SystemConfigDto>) => {
@ -38,8 +36,6 @@
notificationController.show({ message: $t('settings_saved'), type: NotificationType.Info }); notificationController.show({ message: $t('settings_saved'), type: NotificationType.Info });
await loadConfig(); await loadConfig();
dispatch('save');
} catch (error) { } catch (error) {
handleError(error, $t('errors.unable_to_save_settings')); handleError(error, $t('errors.unable_to_save_settings'));
} }

View File

@ -1,7 +1,15 @@
import type { ResetOptions } from '$lib/utils/dipatch'; import type { ResetOptions } from '$lib/utils/dipatch';
import type { SystemConfigDto } from '@immich/sdk'; import type { SystemConfigDto } from '@immich/sdk';
export type SettingsEventType = { export type SettingsResetOptions = ResetOptions & { configKeys: Array<keyof SystemConfigDto> };
reset: ResetOptions & { configKeys: Array<keyof SystemConfigDto> }; export type SettingsResetEvent = (options: SettingsResetOptions) => void;
save: Partial<SystemConfigDto>; export type SettingsSaveEvent = (config: Partial<SystemConfigDto>) => void;
export type SettingsComponentProps = {
disabled?: boolean;
defaultConfig: SystemConfigDto;
config: SystemConfigDto;
savedConfig: SystemConfigDto;
onReset: SettingsResetEvent;
onSave: SettingsSaveEvent;
}; };

View File

@ -8,9 +8,8 @@
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte'; import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
import { type SystemConfigDto } from '@immich/sdk'; import { type SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
import FormatMessage from '$lib/components/i18n/format-message.svelte'; import FormatMessage from '$lib/components/i18n/format-message.svelte';
@ -18,8 +17,8 @@
export let defaultConfig: SystemConfigDto; export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let onReset: SettingsResetEvent;
const dispatch = createEventDispatcher<SettingsEventType>(); export let onSave: SettingsSaveEvent;
let isConfirmOpen = false; let isConfirmOpen = false;
@ -39,7 +38,7 @@
} }
isConfirmOpen = false; isConfirmOpen = false;
dispatch('save', { passwordLogin: config.passwordLogin, oauth: config.oauth }); onSave({ passwordLogin: config.passwordLogin, oauth: config.oauth });
}; };
</script> </script>
@ -240,8 +239,8 @@
showResetToDefault={!isEqual(savedConfig.passwordLogin, defaultConfig.passwordLogin) || showResetToDefault={!isEqual(savedConfig.passwordLogin, defaultConfig.passwordLogin) ||
!isEqual(savedConfig.oauth, defaultConfig.oauth)} !isEqual(savedConfig.oauth, defaultConfig.oauth)}
{disabled} {disabled}
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['passwordLogin', 'oauth'] })} onReset={(options) => onReset({ ...options, configKeys: ['passwordLogin', 'oauth'] })}
on:save={() => handleSave(false)} onSave={() => handleSave(false)}
/> />
</div> </div>
</form> </form>

View File

@ -11,9 +11,8 @@
} from '@immich/sdk'; } from '@immich/sdk';
import { mdiHelpCircleOutline } from '@mdi/js'; import { mdiHelpCircleOutline } from '@mdi/js';
import { isEqual, sortBy } from 'lodash-es'; import { isEqual, sortBy } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.svelte'; import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.svelte';
import SettingInputField, { import SettingInputField, {
SettingInputFieldType, SettingInputFieldType,
@ -29,8 +28,8 @@
export let defaultConfig: SystemConfigDto; export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let onReset: SettingsResetEvent;
const dispatch = createEventDispatcher<SettingsEventType>(); export let onSave: SettingsSaveEvent;
</script> </script>
<div> <div>
@ -368,8 +367,8 @@
<div class="ml-4"> <div class="ml-4">
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['ffmpeg'] })} onReset={(options) => onReset({ ...options, configKeys: ['ffmpeg'] })}
on:save={() => dispatch('save', { ffmpeg: config.ffmpeg })} onSave={() => onSave({ ffmpeg: config.ffmpeg })}
showResetToDefault={!isEqual(savedConfig.ffmpeg, defaultConfig.ffmpeg)} showResetToDefault={!isEqual(savedConfig.ffmpeg, defaultConfig.ffmpeg)}
{disabled} {disabled}
/> />

View File

@ -1,9 +1,8 @@
<script lang="ts"> <script lang="ts">
import { Colorspace, ImageFormat, type SystemConfigDto } from '@immich/sdk'; import { Colorspace, ImageFormat, type SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import SettingSelect from '$lib/components/shared-components/settings/setting-select.svelte'; import SettingSelect from '$lib/components/shared-components/settings/setting-select.svelte';
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte'; import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
@ -17,8 +16,8 @@
export let defaultConfig: SystemConfigDto; export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let onReset: SettingsResetEvent;
const dispatch = createEventDispatcher<SettingsEventType>(); export let onSave: SettingsSaveEvent;
</script> </script>
<div> <div>
@ -114,8 +113,8 @@
<div class="ml-4"> <div class="ml-4">
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['image'] })} onReset={(options) => onReset({ ...options, configKeys: ['image'] })}
on:save={() => dispatch('save', { image: config.image })} onSave={() => onSave({ image: config.image })}
showResetToDefault={!isEqual(savedConfig.image, defaultConfig.image)} showResetToDefault={!isEqual(savedConfig.image, defaultConfig.image)}
{disabled} {disabled}
/> />

View File

@ -2,9 +2,8 @@
import { getJobName } from '$lib/utils'; import { getJobName } from '$lib/utils';
import { JobName, type SystemConfigDto, type SystemConfigJobDto } from '@immich/sdk'; import { JobName, type SystemConfigDto, type SystemConfigJobDto } from '@immich/sdk';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte'; import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
import SettingInputField, { import SettingInputField, {
SettingInputFieldType, SettingInputFieldType,
@ -15,8 +14,8 @@
export let defaultConfig: SystemConfigDto; export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let onReset: SettingsResetEvent;
const dispatch = createEventDispatcher<SettingsEventType>(); export let onSave: SettingsSaveEvent;
const jobNames = [ const jobNames = [
JobName.ThumbnailGeneration, JobName.ThumbnailGeneration,
@ -67,8 +66,8 @@
<div class="ml-4"> <div class="ml-4">
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['job'] })} onReset={(options) => onReset({ ...options, configKeys: ['job'] })}
on:save={() => dispatch('save', { job: config.job })} onSave={() => onSave({ job: config.job })}
showResetToDefault={!isEqual(savedConfig.job, defaultConfig.job)} showResetToDefault={!isEqual(savedConfig.job, defaultConfig.job)}
{disabled} {disabled}
/> />

View File

@ -1,9 +1,8 @@
<script lang="ts"> <script lang="ts">
import type { SystemConfigDto } from '@immich/sdk'; import type { SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.svelte'; import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.svelte';
import SettingInputField, { import SettingInputField, {
SettingInputFieldType, SettingInputFieldType,
@ -17,6 +16,8 @@
export let defaultConfig: SystemConfigDto; export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let onReset: SettingsResetEvent;
export let onSave: SettingsSaveEvent;
$: cronExpressionOptions = [ $: cronExpressionOptions = [
{ title: $t('interval.night_at_midnight'), expression: '0 0 * * *' }, { title: $t('interval.night_at_midnight'), expression: '0 0 * * *' },
@ -24,8 +25,6 @@
{ title: $t('interval.day_at_onepm'), expression: '0 13 * * *' }, { title: $t('interval.day_at_onepm'), expression: '0 13 * * *' },
{ title: $t('interval.hours', { values: { hours: 6 } }), expression: '0 */6 * * *' }, { title: $t('interval.hours', { values: { hours: 6 } }), expression: '0 */6 * * *' },
]; ];
const dispatch = createEventDispatcher<SettingsEventType>();
</script> </script>
<div> <div>
@ -47,8 +46,8 @@
<div class="ml-4"> <div class="ml-4">
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['library'] })} onReset={(options) => onReset({ ...options, configKeys: ['library'] })}
on:save={() => dispatch('save', { library: config.library })} onSave={() => onSave({ library: config.library })}
showResetToDefault={!isEqual(savedConfig.library, defaultConfig.library)} showResetToDefault={!isEqual(savedConfig.library, defaultConfig.library)}
{disabled} {disabled}
/> />
@ -112,8 +111,8 @@
<div class="ml-4"> <div class="ml-4">
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['library'] })} onReset={(options) => onReset({ ...options, configKeys: ['library'] })}
on:save={() => dispatch('save', { library: config.library })} onSave={() => onSave({ library: config.library })}
showResetToDefault={!isEqual(savedConfig.library, defaultConfig.library)} showResetToDefault={!isEqual(savedConfig.library, defaultConfig.library)}
{disabled} {disabled}
/> />

View File

@ -1,9 +1,8 @@
<script lang="ts"> <script lang="ts">
import { LogLevel, type SystemConfigDto } from '@immich/sdk'; import { LogLevel, type SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.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 SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
import SettingSelect from '$lib/components/shared-components/settings/setting-select.svelte'; import SettingSelect from '$lib/components/shared-components/settings/setting-select.svelte';
@ -13,8 +12,8 @@
export let defaultConfig: SystemConfigDto; export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let onReset: SettingsResetEvent;
const dispatch = createEventDispatcher<SettingsEventType>(); export let onSave: SettingsSaveEvent;
</script> </script>
<div> <div>
@ -44,8 +43,8 @@
/> />
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['logging'] })} onReset={(options) => onReset({ ...options, configKeys: ['logging'] })}
on:save={() => dispatch('save', { logging: config.logging })} onSave={() => onSave({ logging: config.logging })}
showResetToDefault={!isEqual(savedConfig.logging, defaultConfig.logging)} showResetToDefault={!isEqual(savedConfig.logging, defaultConfig.logging)}
{disabled} {disabled}
/> />

View File

@ -1,9 +1,8 @@
<script lang="ts"> <script lang="ts">
import type { SystemConfigDto } from '@immich/sdk'; import type { SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.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 SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
import SettingInputField, { import SettingInputField, {
@ -19,8 +18,8 @@
export let defaultConfig: SystemConfigDto; export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let onReset: SettingsResetEvent;
const dispatch = createEventDispatcher<SettingsEventType>(); export let onSave: SettingsSaveEvent;
</script> </script>
<div class="mt-2"> <div class="mt-2">
@ -181,8 +180,8 @@
</SettingAccordion> </SettingAccordion>
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['machineLearning'] })} onReset={(options) => onReset({ ...options, configKeys: ['machineLearning'] })}
on:save={() => dispatch('save', { machineLearning: config.machineLearning })} onSave={() => onSave({ machineLearning: config.machineLearning })}
showResetToDefault={!isEqual(savedConfig.machineLearning, defaultConfig.machineLearning)} showResetToDefault={!isEqual(savedConfig.machineLearning, defaultConfig.machineLearning)}
{disabled} {disabled}
/> />

View File

@ -1,9 +1,8 @@
<script lang="ts"> <script lang="ts">
import type { SystemConfigDto } from '@immich/sdk'; import type { SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.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 SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte'; import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
@ -17,8 +16,8 @@
export let defaultConfig: SystemConfigDto; export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let onReset: SettingsResetEvent;
const dispatch = createEventDispatcher<SettingsEventType>(); export let onSave: SettingsSaveEvent;
</script> </script>
<div class="mt-2"> <div class="mt-2">
@ -75,8 +74,8 @@
> >
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['map', 'reverseGeocoding'] })} onReset={(options) => onReset({ ...options, configKeys: ['map', 'reverseGeocoding'] })}
on:save={() => dispatch('save', { map: config.map, reverseGeocoding: config.reverseGeocoding })} onSave={() => onSave({ map: config.map, reverseGeocoding: config.reverseGeocoding })}
showResetToDefault={!isEqual( showResetToDefault={!isEqual(
{ map: savedConfig.map, reverseGeocoding: savedConfig.reverseGeocoding }, { map: savedConfig.map, reverseGeocoding: savedConfig.reverseGeocoding },
{ map: defaultConfig.map, reverseGeocoding: defaultConfig.reverseGeocoding }, { map: defaultConfig.map, reverseGeocoding: defaultConfig.reverseGeocoding },

View File

@ -1,9 +1,8 @@
<script lang="ts"> <script lang="ts">
import type { SystemConfigDto } from '@immich/sdk'; import type { SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.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 SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
@ -12,8 +11,8 @@
export let defaultConfig: SystemConfigDto; export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let onReset: SettingsResetEvent;
const dispatch = createEventDispatcher<SettingsEventType>(); export let onSave: SettingsSaveEvent;
</script> </script>
<div> <div>
@ -26,8 +25,8 @@
{disabled} {disabled}
/> />
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['newVersionCheck'] })} onReset={(options) => onReset({ ...options, configKeys: ['newVersionCheck'] })}
on:save={() => dispatch('save', { newVersionCheck: config.newVersionCheck })} onSave={() => onSave({ newVersionCheck: config.newVersionCheck })}
showResetToDefault={!isEqual(savedConfig.newVersionCheck, defaultConfig.newVersionCheck)} showResetToDefault={!isEqual(savedConfig.newVersionCheck, defaultConfig.newVersionCheck)}
{disabled} {disabled}
/> />

View File

@ -1,9 +1,8 @@
<script lang="ts"> <script lang="ts">
import { sendTestEmail, type SystemConfigDto } from '@immich/sdk'; import { sendTestEmail, type SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import SettingInputField, { import SettingInputField, {
SettingInputFieldType, SettingInputFieldType,
} from '$lib/components/shared-components/settings/setting-input-field.svelte'; } from '$lib/components/shared-components/settings/setting-input-field.svelte';
@ -24,8 +23,10 @@
export let defaultConfig: SystemConfigDto; export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let onReset: SettingsResetEvent;
export let onSave: SettingsSaveEvent;
let isSending = false; let isSending = false;
const dispatch = createEventDispatcher<SettingsEventType>();
const handleSendTestEmail = async () => { const handleSendTestEmail = async () => {
if (isSending) { if (isSending) {
@ -56,7 +57,7 @@
}); });
if (!disabled) { if (!disabled) {
dispatch('save', { notifications: config.notifications }); onSave({ notifications: config.notifications });
} }
} catch (error) { } catch (error) {
handleError(error, $t('admin.notification_email_test_email_failed')); handleError(error, $t('admin.notification_email_test_email_failed'));
@ -156,8 +157,8 @@
</div> </div>
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['notifications'] })} onReset={(options) => onReset({ ...options, configKeys: ['notifications'] })}
on:save={() => dispatch('save', { notifications: config.notifications })} onSave={() => onSave({ notifications: config.notifications })}
showResetToDefault={!isEqual(savedConfig, defaultConfig)} showResetToDefault={!isEqual(savedConfig, defaultConfig)}
{disabled} {disabled}
/> />

View File

@ -1,9 +1,8 @@
<script lang="ts"> <script lang="ts">
import type { SystemConfigDto } from '@immich/sdk'; import type { SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import SettingInputField, { import SettingInputField, {
SettingInputFieldType, SettingInputFieldType,
} from '$lib/components/shared-components/settings/setting-input-field.svelte'; } from '$lib/components/shared-components/settings/setting-input-field.svelte';
@ -14,8 +13,8 @@
export let defaultConfig: SystemConfigDto; export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let onReset: SettingsResetEvent;
const dispatch = createEventDispatcher<SettingsEventType>(); export let onSave: SettingsSaveEvent;
</script> </script>
<div> <div>
@ -40,8 +39,8 @@
<div class="ml-4"> <div class="ml-4">
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['server'] })} onReset={(options) => onReset({ ...options, configKeys: ['server'] })}
on:save={() => dispatch('save', { server: config.server })} onSave={() => onSave({ server: config.server })}
showResetToDefault={!isEqual(savedConfig.server, defaultConfig.server)} showResetToDefault={!isEqual(savedConfig.server, defaultConfig.server)}
{disabled} {disabled}
/> />

View File

@ -10,9 +10,8 @@
import handlebar from 'handlebars'; import handlebar from 'handlebars';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import * as luxon from 'luxon'; import * as luxon from 'luxon';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import SupportedDatetimePanel from './supported-datetime-panel.svelte'; import SupportedDatetimePanel from './supported-datetime-panel.svelte';
import SupportedVariablesPanel from './supported-variables-panel.svelte'; import SupportedVariablesPanel from './supported-variables-panel.svelte';
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte'; import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
@ -28,8 +27,9 @@
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let minified = false; export let minified = false;
export let onReset: SettingsResetEvent;
export let onSave: SettingsSaveEvent;
const dispatch = createEventDispatcher<SettingsEventType>();
let templateOptions: SystemConfigTemplateStorageOptionDto; let templateOptions: SystemConfigTemplateStorageOptionDto;
let selectedPreset = ''; let selectedPreset = '';
@ -249,8 +249,8 @@
<slot /> <slot />
{:else} {:else}
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['storageTemplate'] })} onReset={(options) => onReset({ ...options, configKeys: ['storageTemplate'] })}
on:save={() => dispatch('save', { storageTemplate: config.storageTemplate })} onSave={() => onSave({ storageTemplate: config.storageTemplate })}
showResetToDefault={!isEqual(savedConfig.storageTemplate, defaultConfig.storageTemplate) && !minified} showResetToDefault={!isEqual(savedConfig.storageTemplate, defaultConfig.storageTemplate) && !minified}
{disabled} {disabled}
/> />

View File

@ -1,9 +1,8 @@
<script lang="ts"> <script lang="ts">
import type { SystemConfigDto } from '@immich/sdk'; import type { SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import SettingTextarea from '$lib/components/shared-components/settings/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'; import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
@ -12,8 +11,8 @@
export let defaultConfig: SystemConfigDto; export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let onReset: SettingsResetEvent;
const dispatch = createEventDispatcher<SettingsEventType>(); export let onSave: SettingsSaveEvent;
</script> </script>
<div> <div>
@ -30,8 +29,8 @@
/> />
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['theme'] })} onReset={(options) => onReset({ ...options, configKeys: ['theme'] })}
on:save={() => dispatch('save', { theme: config.theme })} onSave={() => onSave({ theme: config.theme })}
showResetToDefault={!isEqual(savedConfig, defaultConfig)} showResetToDefault={!isEqual(savedConfig, defaultConfig)}
{disabled} {disabled}
/> />

View File

@ -1,9 +1,8 @@
<script lang="ts"> <script lang="ts">
import type { SystemConfigDto } from '@immich/sdk'; import type { SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte'; import SettingSwitch from '$lib/components/shared-components/settings/setting-switch.svelte';
import SettingInputField, { import SettingInputField, {
SettingInputFieldType, SettingInputFieldType,
@ -15,8 +14,8 @@
export let defaultConfig: SystemConfigDto; export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let onReset: SettingsResetEvent;
const dispatch = createEventDispatcher<SettingsEventType>(); export let onSave: SettingsSaveEvent;
</script> </script>
<div> <div>
@ -38,8 +37,8 @@
/> />
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['trash'] })} onReset={(options) => onReset({ ...options, configKeys: ['trash'] })}
on:save={() => dispatch('save', { trash: config.trash })} onSave={() => onSave({ trash: config.trash })}
showResetToDefault={!isEqual(savedConfig.trash, defaultConfig.trash)} showResetToDefault={!isEqual(savedConfig.trash, defaultConfig.trash)}
{disabled} {disabled}
/> />

View File

@ -1,9 +1,8 @@
<script lang="ts"> <script lang="ts">
import { type SystemConfigDto } from '@immich/sdk'; import { type SystemConfigDto } from '@immich/sdk';
import { isEqual } from 'lodash-es'; import { isEqual } from 'lodash-es';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import type { SettingsEventType } from '../admin-settings'; import type { SettingsResetEvent, SettingsSaveEvent } from '../admin-settings';
import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte'; import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte';
import SettingInputField, { import SettingInputField, {
@ -15,8 +14,8 @@
export let defaultConfig: SystemConfigDto; export let defaultConfig: SystemConfigDto;
export let config: SystemConfigDto; // this is the config that is being edited export let config: SystemConfigDto; // this is the config that is being edited
export let disabled = false; export let disabled = false;
export let onReset: SettingsResetEvent;
const dispatch = createEventDispatcher<SettingsEventType>(); export let onSave: SettingsSaveEvent;
</script> </script>
<div> <div>
@ -35,8 +34,8 @@
<div class="ml-4"> <div class="ml-4">
<SettingButtonsRow <SettingButtonsRow
on:reset={({ detail }) => dispatch('reset', { ...detail, configKeys: ['user'] })} onReset={(options) => onReset({ ...options, configKeys: ['user'] })}
on:save={() => dispatch('save', { user: config.user })} onSave={() => onSave({ user: config.user })}
showResetToDefault={!isEqual(savedConfig.user, defaultConfig.user)} showResetToDefault={!isEqual(savedConfig.user, defaultConfig.user)}
{disabled} {disabled}
/> />

View File

@ -43,8 +43,8 @@
{config} {config}
{defaultConfig} {defaultConfig}
{savedConfig} {savedConfig}
on:save={({ detail }) => handleSave(detail)} onSave={(config) => handleSave(config)}
on:reset={({ detail }) => handleReset(detail)} onReset={(options) => handleReset(options)}
> >
<div class="flex pt-4"> <div class="flex pt-4">
<div class="w-full flex place-content-start"> <div class="w-full flex place-content-start">

View File

@ -1,16 +1,12 @@
<script lang="ts"> <script lang="ts">
import Button from '$lib/components/elements/buttons/button.svelte'; import Button from '$lib/components/elements/buttons/button.svelte';
import type { ResetOptions } from '$lib/utils/dipatch'; import type { ResetOptions } from '$lib/utils/dipatch';
import { createEventDispatcher } from 'svelte';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
const dispatch = createEventDispatcher<{
reset: ResetOptions;
save: void;
}>();
export let showResetToDefault = true; export let showResetToDefault = true;
export let disabled = false; export let disabled = false;
export let onReset: (options: ResetOptions) => void;
export let onSave: () => void;
</script> </script>
<div class="mt-8 flex justify-between gap-2"> <div class="mt-8 flex justify-between gap-2">
@ -18,7 +14,7 @@
{#if showResetToDefault} {#if showResetToDefault}
<button <button
type="button" type="button"
on:click={() => dispatch('reset', { default: true })} on:click={() => onReset({ 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" 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"
> >
{$t('reset_to_default')} {$t('reset_to_default')}
@ -27,9 +23,7 @@
</div> </div>
<div class="right"> <div class="right">
<Button {disabled} size="sm" color="gray" on:click={() => dispatch('reset', { default: false })} <Button {disabled} size="sm" color="gray" on:click={() => onReset({ default: false })}>{$t('reset')}</Button>
>{$t('reset')}</Button <Button type="submit" {disabled} size="sm" on:click={() => onSave()}>{$t('save')}</Button>
>
<Button type="submit" {disabled} size="sm" on:click={() => dispatch('save')}>{$t('save')}</Button>
</div> </div>
</div> </div>

View File

@ -29,28 +29,15 @@
import { mdiAlert, mdiContentCopy, mdiDownload, mdiUpload } from '@mdi/js'; import { mdiAlert, mdiContentCopy, mdiDownload, mdiUpload } from '@mdi/js';
import type { PageData } from './$types'; import type { PageData } from './$types';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
import type { ComponentType, SvelteComponent } from 'svelte';
import type { SettingsComponentProps } from '$lib/components/admin-page/settings/admin-settings';
export let data: PageData; export let data: PageData;
let config = data.configs; let config = data.configs;
let handleSave: (update: Partial<SystemConfigDto>) => Promise<void>; let handleSave: (update: Partial<SystemConfigDto>) => Promise<void>;
type Settings = type SettingsComponent = ComponentType<SvelteComponent<SettingsComponentProps>>;
| typeof AuthSettings
| typeof JobSettings
| typeof LibrarySettings
| typeof LoggingSettings
| typeof MachineLearningSettings
| typeof MapSettings
| typeof ServerSettings
| typeof StorageTemplateSettings
| typeof ThemeSettings
| typeof ImageSettings
| typeof TrashSettings
| typeof NewVersionCheckSettings
| typeof NotificationSettings
| typeof FFmpegSettings
| typeof UserSettings;
const downloadConfig = () => { const downloadConfig = () => {
const blob = new Blob([JSON.stringify(config, null, 2)], { type: 'application/json' }); const blob = new Blob([JSON.stringify(config, null, 2)], { type: 'application/json' });
@ -76,97 +63,97 @@
}; };
const settings: Array<{ const settings: Array<{
item: Settings; component: SettingsComponent;
title: string; title: string;
subtitle: string; subtitle: string;
key: string; key: string;
}> = [ }> = [
{ {
item: AuthSettings, component: AuthSettings,
title: $t('admin.authentication_settings'), title: $t('admin.authentication_settings'),
subtitle: $t('admin.authentication_settings_description'), subtitle: $t('admin.authentication_settings_description'),
key: 'image', key: 'image',
}, },
{ {
item: ImageSettings, component: ImageSettings,
title: $t('admin.image_settings'), title: $t('admin.image_settings'),
subtitle: $t('admin.image_settings_description'), subtitle: $t('admin.image_settings_description'),
key: 'image', key: 'image',
}, },
{ {
item: JobSettings, component: JobSettings,
title: $t('admin.job_settings'), title: $t('admin.job_settings'),
subtitle: $t('admin.job_settings_description'), subtitle: $t('admin.job_settings_description'),
key: 'job', key: 'job',
}, },
{ {
item: LibrarySettings, component: LibrarySettings,
title: $t('admin.library_settings'), title: $t('admin.library_settings'),
subtitle: $t('admin.library_settings_description'), subtitle: $t('admin.library_settings_description'),
key: 'external-library', key: 'external-library',
}, },
{ {
item: LoggingSettings, component: LoggingSettings,
title: $t('admin.logging_settings'), title: $t('admin.logging_settings'),
subtitle: $t('admin.manage_log_settings'), subtitle: $t('admin.manage_log_settings'),
key: 'logging', key: 'logging',
}, },
{ {
item: MachineLearningSettings, component: MachineLearningSettings,
title: $t('admin.machine_learning_settings'), title: $t('admin.machine_learning_settings'),
subtitle: $t('admin.machine_learning_settings_description'), subtitle: $t('admin.machine_learning_settings_description'),
key: 'machine-learning', key: 'machine-learning',
}, },
{ {
item: MapSettings, component: MapSettings,
title: $t('admin.map_settings'), title: $t('admin.map_settings'),
subtitle: $t('admin.map_settings_description'), subtitle: $t('admin.map_settings_description'),
key: 'location', key: 'location',
}, },
{ {
item: NotificationSettings, component: NotificationSettings,
title: $t('admin.notification_settings'), title: $t('admin.notification_settings'),
subtitle: $t('admin.notification_settings_description'), subtitle: $t('admin.notification_settings_description'),
key: 'notifications', key: 'notifications',
}, },
{ {
item: ServerSettings, component: ServerSettings,
title: $t('admin.server_settings'), title: $t('admin.server_settings'),
subtitle: $t('admin.server_settings_description'), subtitle: $t('admin.server_settings_description'),
key: 'server', key: 'server',
}, },
{ {
item: StorageTemplateSettings, component: StorageTemplateSettings,
title: $t('admin.storage_template_settings'), title: $t('admin.storage_template_settings'),
subtitle: $t('admin.storage_template_settings_description'), subtitle: $t('admin.storage_template_settings_description'),
key: 'storage-template', key: 'storage-template',
}, },
{ {
item: ThemeSettings, component: ThemeSettings,
title: $t('admin.theme_settings'), title: $t('admin.theme_settings'),
subtitle: $t('admin.theme_settings_description'), subtitle: $t('admin.theme_settings_description'),
key: 'theme', key: 'theme',
}, },
{ {
item: TrashSettings, component: TrashSettings,
title: $t('admin.trash_settings'), title: $t('admin.trash_settings'),
subtitle: $t('admin.trash_settings_description'), subtitle: $t('admin.trash_settings_description'),
key: 'trash', key: 'trash',
}, },
{ {
item: UserSettings, component: UserSettings,
title: $t('admin.user_settings'), title: $t('admin.user_settings'),
subtitle: $t('admin.user_settings_description'), subtitle: $t('admin.user_settings_description'),
key: 'user-settings', key: 'user-settings',
}, },
{ {
item: NewVersionCheckSettings, component: NewVersionCheckSettings,
title: $t('admin.version_check_settings'), title: $t('admin.version_check_settings'),
subtitle: $t('admin.version_check_settings_description'), subtitle: $t('admin.version_check_settings_description'),
key: 'version-check', key: 'version-check',
}, },
{ {
item: FFmpegSettings, component: FFmpegSettings,
title: $t('admin.transcoding_settings'), title: $t('admin.transcoding_settings'),
subtitle: $t('admin.transcoding_settings_description'), subtitle: $t('admin.transcoding_settings_description'),
key: 'video-transcoding', key: 'video-transcoding',
@ -212,12 +199,11 @@
<section id="setting-content" class="flex place-content-center sm:mx-4"> <section id="setting-content" class="flex place-content-center sm:mx-4">
<section class="w-full pb-28 sm:w-5/6 md:w-[850px]"> <section class="w-full pb-28 sm:w-5/6 md:w-[850px]">
<SettingAccordionState queryParam={QueryParameter.IS_OPEN}> <SettingAccordionState queryParam={QueryParameter.IS_OPEN}>
{#each settings as { item, title, subtitle, key }} {#each settings as { component: Component, title, subtitle, key }}
<SettingAccordion {title} {subtitle} {key}> <SettingAccordion {title} {subtitle} {key}>
<svelte:component <Component
this={item} onSave={(config) => handleSave(config)}
on:save={({ detail }) => handleSave(detail)} onReset={(options) => handleReset(options)}
on:reset={({ detail }) => handleReset(detail)}
disabled={$featureFlags.configFile} disabled={$featureFlags.configFile}
{defaultConfig} {defaultConfig}
{config} {config}