Compare commits
11 commits
main
...
refactor/s
Author | SHA1 | Date | |
---|---|---|---|
|
1cb58728b2 | ||
|
406754195b | ||
|
1d544c8c4d | ||
|
7226d12d5d | ||
|
8b7a4f2169 | ||
|
77fb3e9ce2 | ||
|
4e98b1001b | ||
|
6e2ba7acab | ||
|
3674e5b858 | ||
|
4b1e1f6e83 | ||
|
0e4b00d07a |
9 changed files with 846 additions and 980 deletions
|
@ -3,79 +3,35 @@
|
|||
notificationController,
|
||||
NotificationType,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import {
|
||||
api,
|
||||
AudioCodec,
|
||||
SystemConfigFFmpegDto,
|
||||
ToneMapping,
|
||||
TranscodeHWAccel,
|
||||
TranscodePolicy,
|
||||
VideoCodec,
|
||||
} from '@api';
|
||||
import { AudioCodec, SystemConfigFFmpegDto, ToneMapping, TranscodeHWAccel, TranscodePolicy, VideoCodec } from '@api';
|
||||
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 { isEqual } from 'lodash-es';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
export let ffmpegConfig: SystemConfigFFmpegDto; // this is the config that is being edited
|
||||
export let ffmpegDefault: SystemConfigFFmpegDto;
|
||||
export let savedConfig: SystemConfigFFmpegDto;
|
||||
export let disabled = false;
|
||||
|
||||
let savedConfig: SystemConfigFFmpegDto;
|
||||
let defaultConfig: SystemConfigFFmpegDto;
|
||||
|
||||
async function getConfigs() {
|
||||
[savedConfig, defaultConfig] = await Promise.all([
|
||||
api.systemConfigApi.getConfig().then((res) => res.data.ffmpeg),
|
||||
api.systemConfigApi.getDefaults().then((res) => res.data.ffmpeg),
|
||||
]);
|
||||
}
|
||||
|
||||
async function saveSetting() {
|
||||
try {
|
||||
const { data: configs } = await api.systemConfigApi.getConfig();
|
||||
|
||||
const result = await api.systemConfigApi.updateConfig({
|
||||
systemConfigDto: {
|
||||
...configs,
|
||||
ffmpeg: ffmpegConfig,
|
||||
},
|
||||
});
|
||||
|
||||
ffmpegConfig = { ...result.data.ffmpeg };
|
||||
savedConfig = { ...result.data.ffmpeg };
|
||||
|
||||
notificationController.show({
|
||||
message: 'FFmpeg settings saved',
|
||||
type: NotificationType.Info,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Error [ffmpeg-settings] [saveSetting]', e);
|
||||
notificationController.show({
|
||||
message: 'Unable to save settings',
|
||||
type: NotificationType.Error,
|
||||
});
|
||||
}
|
||||
}
|
||||
const dispatch = createEventDispatcher<{
|
||||
save: SystemConfigFFmpegDto;
|
||||
}>();
|
||||
|
||||
async function reset() {
|
||||
const { data: resetConfig } = await api.systemConfigApi.getConfig();
|
||||
|
||||
ffmpegConfig = { ...resetConfig.ffmpeg };
|
||||
savedConfig = { ...resetConfig.ffmpeg };
|
||||
ffmpegConfig = { ...savedConfig };
|
||||
|
||||
notificationController.show({
|
||||
message: 'Reset FFmpeg settings to the recent saved settings',
|
||||
message: 'Reset FFmpeg settings to the last saved settings',
|
||||
type: NotificationType.Info,
|
||||
});
|
||||
}
|
||||
|
||||
async function resetToDefault() {
|
||||
const { data: configs } = await api.systemConfigApi.getDefaults();
|
||||
|
||||
ffmpegConfig = { ...configs.ffmpeg };
|
||||
defaultConfig = { ...configs.ffmpeg };
|
||||
ffmpegConfig = { ...ffmpegDefault };
|
||||
|
||||
notificationController.show({
|
||||
message: 'Reset FFmpeg settings to default',
|
||||
|
@ -85,8 +41,7 @@
|
|||
</script>
|
||||
|
||||
<div>
|
||||
{#await getConfigs() then}
|
||||
<div in:fade={{ duration: 500 }}>
|
||||
<div in:fade={{ duration: 300 }}>
|
||||
<form autocomplete="off" on:submit|preventDefault>
|
||||
<div class="ml-4 mt-4 flex flex-col gap-4">
|
||||
<SettingInputField
|
||||
|
@ -269,13 +224,12 @@
|
|||
<div class="ml-4">
|
||||
<SettingButtonsRow
|
||||
on:reset={reset}
|
||||
on:save={saveSetting}
|
||||
on:save={() => dispatch('save', ffmpegConfig)}
|
||||
on:reset-to-default={resetToDefault}
|
||||
showResetToDefault={!isEqual(savedConfig, defaultConfig)}
|
||||
showResetToDefault={!isEqual(ffmpegConfig, ffmpegDefault)}
|
||||
{disabled}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{/await}
|
||||
</div>
|
||||
|
|
|
@ -6,51 +6,24 @@
|
|||
import { api, JobName, SystemConfigJobDto } from '@api';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { handleError } from '../../../../utils/handle-error';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
save: SystemConfigJobDto;
|
||||
}>();
|
||||
|
||||
export let jobConfig: SystemConfigJobDto; // this is the config that is being edited
|
||||
export let jobDefault: SystemConfigJobDto;
|
||||
export let savedConfig: SystemConfigJobDto;
|
||||
export let disabled = false;
|
||||
|
||||
let savedConfig: SystemConfigJobDto;
|
||||
let defaultConfig: SystemConfigJobDto;
|
||||
|
||||
const ignoredJobs = [JobName.BackgroundTask, JobName.Search] as JobName[];
|
||||
const jobNames = Object.values(JobName).filter((jobName) => !ignoredJobs.includes(jobName as JobName));
|
||||
|
||||
async function getConfigs() {
|
||||
[savedConfig, defaultConfig] = await Promise.all([
|
||||
api.systemConfigApi.getConfig().then((res) => res.data.job),
|
||||
api.systemConfigApi.getDefaults().then((res) => res.data.job),
|
||||
]);
|
||||
}
|
||||
|
||||
async function saveSetting() {
|
||||
try {
|
||||
const { data: configs } = await api.systemConfigApi.getConfig();
|
||||
|
||||
const result = await api.systemConfigApi.updateConfig({
|
||||
systemConfigDto: {
|
||||
...configs,
|
||||
job: jobConfig,
|
||||
},
|
||||
});
|
||||
|
||||
jobConfig = { ...result.data.job };
|
||||
savedConfig = { ...result.data.job };
|
||||
|
||||
notificationController.show({ message: 'Job settings saved', type: NotificationType.Info });
|
||||
} catch (error) {
|
||||
handleError(error, 'Unable to save settings');
|
||||
}
|
||||
}
|
||||
|
||||
async function reset() {
|
||||
const { data: resetConfig } = await api.systemConfigApi.getConfig();
|
||||
|
||||
jobConfig = { ...resetConfig.job };
|
||||
savedConfig = { ...resetConfig.job };
|
||||
jobConfig = { ...savedConfig };
|
||||
|
||||
notificationController.show({
|
||||
message: 'Reset Job settings to the recent saved settings',
|
||||
|
@ -59,10 +32,7 @@
|
|||
}
|
||||
|
||||
async function resetToDefault() {
|
||||
const { data: configs } = await api.systemConfigApi.getDefaults();
|
||||
|
||||
jobConfig = { ...configs.job };
|
||||
defaultConfig = { ...configs.job };
|
||||
jobConfig = { ...jobDefault };
|
||||
|
||||
notificationController.show({
|
||||
message: 'Reset Job settings to default',
|
||||
|
@ -72,8 +42,7 @@
|
|||
</script>
|
||||
|
||||
<div>
|
||||
{#await getConfigs() then}
|
||||
<div in:fade={{ duration: 500 }}>
|
||||
<div in:fade={{ duration: 300 }}>
|
||||
<form autocomplete="off" on:submit|preventDefault>
|
||||
{#each jobNames as jobName}
|
||||
<div class="ml-4 mt-4 flex flex-col gap-4">
|
||||
|
@ -92,13 +61,11 @@
|
|||
<div class="ml-4">
|
||||
<SettingButtonsRow
|
||||
on:reset={reset}
|
||||
on:save={saveSetting}
|
||||
on:save={() => dispatch('save', jobConfig)}
|
||||
on:reset-to-default={resetToDefault}
|
||||
showResetToDefault={!isEqual(savedConfig, defaultConfig)}
|
||||
{disabled}
|
||||
showResetToDefault={!isEqual(jobConfig, jobDefault)}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{/await}
|
||||
</div>
|
||||
|
|
|
@ -3,60 +3,38 @@
|
|||
notificationController,
|
||||
NotificationType,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { api, SystemConfigMachineLearningDto } from '@api';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { fade } from 'svelte/transition';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import type { SystemConfigMachineLearningDto } from '@api';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import SettingAccordion from '../setting-accordion.svelte';
|
||||
import SettingSelect from '../setting-select.svelte';
|
||||
|
||||
export let machineLearningConfig: SystemConfigMachineLearningDto; // this is the config that is being edited
|
||||
export let disabled = false;
|
||||
|
||||
let savedConfig: SystemConfigMachineLearningDto;
|
||||
let defaultConfig: SystemConfigMachineLearningDto;
|
||||
export let machineLearningConfig: SystemConfigMachineLearningDto; // this is the config that is being edited
|
||||
export let machineLearningDefault: SystemConfigMachineLearningDto;
|
||||
export let savedConfig: SystemConfigMachineLearningDto;
|
||||
|
||||
async function refreshConfig() {
|
||||
[savedConfig, defaultConfig] = await Promise.all([
|
||||
api.systemConfigApi.getConfig().then((res) => res.data.machineLearning),
|
||||
api.systemConfigApi.getDefaults().then((res) => res.data.machineLearning),
|
||||
]);
|
||||
}
|
||||
const dispatch = createEventDispatcher<{
|
||||
save: SystemConfigMachineLearningDto;
|
||||
}>();
|
||||
|
||||
async function reset() {
|
||||
const { data: resetConfig } = await api.systemConfigApi.getConfig();
|
||||
machineLearningConfig = { ...resetConfig.machineLearning };
|
||||
savedConfig = { ...resetConfig.machineLearning };
|
||||
machineLearningConfig = { ...savedConfig };
|
||||
notificationController.show({ message: 'Reset to the last saved settings', type: NotificationType.Info });
|
||||
}
|
||||
|
||||
async function saveSetting() {
|
||||
try {
|
||||
const { data: current } = await api.systemConfigApi.getConfig();
|
||||
const result = await api.systemConfigApi.updateConfig({
|
||||
systemConfigDto: { ...current, machineLearning: machineLearningConfig },
|
||||
});
|
||||
|
||||
machineLearningConfig = { ...result.data.machineLearning };
|
||||
savedConfig = { ...result.data.machineLearning };
|
||||
|
||||
notificationController.show({ message: 'Settings saved', type: NotificationType.Info });
|
||||
} catch (error) {
|
||||
handleError(error, 'Unable to save settings');
|
||||
}
|
||||
}
|
||||
|
||||
async function resetToDefault() {
|
||||
machineLearningConfig = { ...defaultConfig };
|
||||
machineLearningConfig = { ...machineLearningDefault };
|
||||
notificationController.show({ message: 'Reset settings to defaults', type: NotificationType.Info });
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="mt-2">
|
||||
{#await refreshConfig() then}
|
||||
<div in:fade={{ duration: 500 }}>
|
||||
<form autocomplete="off" on:submit|preventDefault class="mx-4 mt-4">
|
||||
<div class="flex flex-col gap-4">
|
||||
|
@ -193,20 +171,18 @@
|
|||
min="0"
|
||||
max="2"
|
||||
disabled={disabled || !machineLearningConfig.enabled || !machineLearningConfig.facialRecognition.enabled}
|
||||
isEdited={machineLearningConfig.facialRecognition.maxDistance !==
|
||||
savedConfig.facialRecognition.maxDistance}
|
||||
isEdited={machineLearningConfig.facialRecognition.maxDistance !== savedConfig.facialRecognition.maxDistance}
|
||||
/>
|
||||
</div>
|
||||
</SettingAccordion>
|
||||
|
||||
<SettingButtonsRow
|
||||
on:reset={reset}
|
||||
on:save={saveSetting}
|
||||
on:save={() => dispatch('save', machineLearningConfig)}
|
||||
on:reset-to-default={resetToDefault}
|
||||
showResetToDefault={!isEqual(savedConfig, defaultConfig)}
|
||||
showResetToDefault={!isEqual(savedConfig, machineLearningConfig)}
|
||||
{disabled}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
{/await}
|
||||
</div>
|
||||
|
|
|
@ -3,21 +3,25 @@
|
|||
notificationController,
|
||||
NotificationType,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { api, SystemConfigOAuthDto } from '@api';
|
||||
import type { SystemConfigDto, SystemConfigOAuthDto } from '@api';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { fade } from 'svelte/transition';
|
||||
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 { createEventDispatcher } from 'svelte';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
save: SystemConfigOAuthDto;
|
||||
}>();
|
||||
|
||||
export let config: SystemConfigDto;
|
||||
export let oauthConfig: SystemConfigOAuthDto;
|
||||
export let oauthDefault: SystemConfigOAuthDto;
|
||||
export let savedConfig: SystemConfigOAuthDto;
|
||||
export let disabled = false;
|
||||
|
||||
let savedConfig: SystemConfigOAuthDto;
|
||||
let defaultConfig: SystemConfigOAuthDto;
|
||||
|
||||
const handleToggleOverride = () => {
|
||||
// click runs before bind
|
||||
const previouslyEnabled = oauthConfig.mobileOverrideEnabled;
|
||||
|
@ -25,19 +29,8 @@
|
|||
oauthConfig.mobileRedirectUri = window.location.origin + '/api/oauth/mobile-redirect';
|
||||
}
|
||||
};
|
||||
|
||||
async function getConfigs() {
|
||||
[savedConfig, defaultConfig] = await Promise.all([
|
||||
api.systemConfigApi.getConfig().then((res) => res.data.oauth),
|
||||
api.systemConfigApi.getDefaults().then((res) => res.data.oauth),
|
||||
]);
|
||||
}
|
||||
|
||||
async function reset() {
|
||||
const { data: resetConfig } = await api.systemConfigApi.getConfig();
|
||||
|
||||
oauthConfig = { ...resetConfig.oauth };
|
||||
savedConfig = { ...resetConfig.oauth };
|
||||
oauthConfig = { ...savedConfig };
|
||||
|
||||
notificationController.show({
|
||||
message: 'Reset OAuth settings to the last saved settings',
|
||||
|
@ -51,6 +44,9 @@
|
|||
const openConfirmModal = () => {
|
||||
return new Promise((resolve) => {
|
||||
handleConfirm = (value: boolean) => {
|
||||
if (!value) {
|
||||
oauthConfig.enabled = !oauthConfig.enabled;
|
||||
}
|
||||
isConfirmOpen = false;
|
||||
resolve(value);
|
||||
};
|
||||
|
@ -59,10 +55,7 @@
|
|||
};
|
||||
|
||||
async function saveSetting() {
|
||||
try {
|
||||
const { data: current } = await api.systemConfigApi.getConfig();
|
||||
|
||||
if (!current.passwordLogin.enabled && current.oauth.enabled && !oauthConfig.enabled) {
|
||||
if (!config.passwordLogin.enabled && savedConfig.enabled && !oauthConfig.enabled) {
|
||||
const confirmed = await openConfirmModal();
|
||||
if (!confirmed) {
|
||||
return;
|
||||
|
@ -73,26 +66,11 @@
|
|||
oauthConfig.mobileRedirectUri = '';
|
||||
}
|
||||
|
||||
const { data: updated } = await api.systemConfigApi.updateConfig({
|
||||
systemConfigDto: {
|
||||
...current,
|
||||
oauth: oauthConfig,
|
||||
},
|
||||
});
|
||||
|
||||
oauthConfig = { ...updated.oauth };
|
||||
savedConfig = { ...updated.oauth };
|
||||
|
||||
notificationController.show({ message: 'OAuth settings saved', type: NotificationType.Info });
|
||||
} catch (error) {
|
||||
handleError(error, 'Unable to save OAuth settings');
|
||||
}
|
||||
dispatch('save', oauthConfig);
|
||||
}
|
||||
|
||||
async function resetToDefault() {
|
||||
const { data: defaultConfig } = await api.systemConfigApi.getDefaults();
|
||||
|
||||
oauthConfig = { ...defaultConfig.oauth };
|
||||
oauthConfig = { ...oauthDefault };
|
||||
|
||||
notificationController.show({
|
||||
message: 'Reset OAuth settings to default',
|
||||
|
@ -106,8 +84,7 @@
|
|||
{/if}
|
||||
|
||||
<div class="mt-2">
|
||||
{#await getConfigs() then}
|
||||
<div in:fade={{ duration: 500 }}>
|
||||
<div in:fade={{ duration: 300 }}>
|
||||
<form autocomplete="off" on:submit|preventDefault class="mx-4 flex flex-col gap-4 py-4">
|
||||
<p class="text-sm dark:text-immich-dark-fg">
|
||||
For more details about this feature, refer to the <a
|
||||
|
@ -118,14 +95,14 @@
|
|||
>.
|
||||
</p>
|
||||
|
||||
<SettingSwitch {disabled} title="ENABLE" bind:checked={oauthConfig.enabled} />
|
||||
<SettingSwitch title="ENABLE" bind:checked={oauthConfig.enabled} />
|
||||
<hr />
|
||||
<SettingInputField
|
||||
inputType={SettingInputFieldType.TEXT}
|
||||
label="ISSUER URL"
|
||||
bind:value={oauthConfig.issuerUrl}
|
||||
required={true}
|
||||
disabled={disabled || !oauthConfig.enabled}
|
||||
disabled={!oauthConfig.enabled}
|
||||
isEdited={!(oauthConfig.issuerUrl == savedConfig.issuerUrl)}
|
||||
/>
|
||||
|
||||
|
@ -134,7 +111,7 @@
|
|||
label="CLIENT ID"
|
||||
bind:value={oauthConfig.clientId}
|
||||
required={true}
|
||||
disabled={disabled || !oauthConfig.enabled}
|
||||
disabled={!oauthConfig.enabled}
|
||||
isEdited={!(oauthConfig.clientId == savedConfig.clientId)}
|
||||
/>
|
||||
|
||||
|
@ -179,7 +156,7 @@
|
|||
title="AUTO REGISTER"
|
||||
subtitle="Automatically register new users after signing in with OAuth"
|
||||
bind:checked={oauthConfig.autoRegister}
|
||||
disabled={disabled || !oauthConfig.enabled}
|
||||
disabled={!oauthConfig.enabled}
|
||||
/>
|
||||
|
||||
<SettingSwitch
|
||||
|
@ -212,10 +189,9 @@
|
|||
on:reset={reset}
|
||||
on:save={saveSetting}
|
||||
on:reset-to-default={resetToDefault}
|
||||
showResetToDefault={!isEqual(savedConfig, defaultConfig)}
|
||||
showResetToDefault={!isEqual(oauthConfig, oauthDefault)}
|
||||
{disabled}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
{/await}
|
||||
</div>
|
||||
|
|
|
@ -3,33 +3,33 @@
|
|||
notificationController,
|
||||
NotificationType,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { api, SystemConfigPasswordLoginDto } from '@api';
|
||||
import type { SystemConfigDto, SystemConfigPasswordLoginDto } from '@api';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { fade } from 'svelte/transition';
|
||||
import ConfirmDisableLogin from '../confirm-disable-login.svelte';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
save: SystemConfigPasswordLoginDto;
|
||||
}>();
|
||||
|
||||
export let config: SystemConfigDto;
|
||||
export let passwordLoginConfig: SystemConfigPasswordLoginDto; // this is the config that is being edited
|
||||
export let passwordLoginDefault: SystemConfigPasswordLoginDto;
|
||||
export let savedConfig: SystemConfigPasswordLoginDto;
|
||||
export let disabled = false;
|
||||
|
||||
let savedConfig: SystemConfigPasswordLoginDto;
|
||||
let defaultConfig: SystemConfigPasswordLoginDto;
|
||||
|
||||
async function getConfigs() {
|
||||
[savedConfig, defaultConfig] = await Promise.all([
|
||||
api.systemConfigApi.getConfig().then((res) => res.data.passwordLogin),
|
||||
api.systemConfigApi.getDefaults().then((res) => res.data.passwordLogin),
|
||||
]);
|
||||
}
|
||||
|
||||
let isConfirmOpen = false;
|
||||
let handleConfirm: (value: boolean) => void;
|
||||
|
||||
const openConfirmModal = () => {
|
||||
return new Promise((resolve) => {
|
||||
handleConfirm = (value: boolean) => {
|
||||
if (!value) {
|
||||
passwordLoginConfig.enabled = !passwordLoginConfig.enabled;
|
||||
}
|
||||
isConfirmOpen = false;
|
||||
resolve(value);
|
||||
};
|
||||
|
@ -38,52 +38,30 @@
|
|||
};
|
||||
|
||||
async function saveSetting() {
|
||||
try {
|
||||
const { data: current } = await api.systemConfigApi.getConfig();
|
||||
|
||||
if (!current.oauth.enabled && current.passwordLogin.enabled && !passwordLoginConfig.enabled) {
|
||||
if (!config.oauth.enabled && savedConfig.enabled && !passwordLoginConfig.enabled) {
|
||||
const confirmed = await openConfirmModal();
|
||||
if (!confirmed) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const { data: updated } = await api.systemConfigApi.updateConfig({
|
||||
systemConfigDto: {
|
||||
...current,
|
||||
passwordLogin: passwordLoginConfig,
|
||||
},
|
||||
});
|
||||
|
||||
passwordLoginConfig = { ...updated.passwordLogin };
|
||||
savedConfig = { ...updated.passwordLogin };
|
||||
|
||||
notificationController.show({ message: 'Settings saved', type: NotificationType.Info });
|
||||
} catch (error) {
|
||||
handleError(error, 'Unable to save settings');
|
||||
}
|
||||
dispatch('save', passwordLoginConfig);
|
||||
}
|
||||
|
||||
async function reset() {
|
||||
const { data: resetConfig } = await api.systemConfigApi.getConfig();
|
||||
|
||||
passwordLoginConfig = { ...resetConfig.passwordLogin };
|
||||
savedConfig = { ...resetConfig.passwordLogin };
|
||||
passwordLoginConfig = { ...savedConfig };
|
||||
|
||||
notificationController.show({
|
||||
message: 'Reset settings to the recent saved settings',
|
||||
message: 'Reset password authentication settings to the last saved settings',
|
||||
type: NotificationType.Info,
|
||||
});
|
||||
}
|
||||
|
||||
async function resetToDefault() {
|
||||
const { data: configs } = await api.systemConfigApi.getDefaults();
|
||||
|
||||
passwordLoginConfig = { ...configs.passwordLogin };
|
||||
defaultConfig = { ...configs.passwordLogin };
|
||||
passwordLoginConfig = { ...passwordLoginDefault };
|
||||
|
||||
notificationController.show({
|
||||
message: 'Reset password settings to default',
|
||||
message: 'Reset password authentication settings to default',
|
||||
type: NotificationType.Info,
|
||||
});
|
||||
}
|
||||
|
@ -94,8 +72,7 @@
|
|||
{/if}
|
||||
|
||||
<div>
|
||||
{#await getConfigs() then}
|
||||
<div in:fade={{ duration: 500 }}>
|
||||
<div in:fade={{ duration: 300 }}>
|
||||
<form autocomplete="off" on:submit|preventDefault>
|
||||
<div class="ml-4 mt-4 flex flex-col gap-4">
|
||||
<div class="ml-4">
|
||||
|
@ -103,6 +80,7 @@
|
|||
title="ENABLED"
|
||||
{disabled}
|
||||
subtitle="Login with email and password"
|
||||
isEdited={!(passwordLoginConfig.enabled == savedConfig.enabled)}
|
||||
bind:checked={passwordLoginConfig.enabled}
|
||||
/>
|
||||
|
||||
|
@ -110,12 +88,11 @@
|
|||
on:reset={reset}
|
||||
on:save={saveSetting}
|
||||
on:reset-to-default={resetToDefault}
|
||||
showResetToDefault={!isEqual(savedConfig, defaultConfig)}
|
||||
showResetToDefault={!isEqual(passwordLoginConfig, passwordLoginDefault)}
|
||||
{disabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{/await}
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { api, SystemConfigStorageTemplateDto, SystemConfigTemplateStorageOptionDto, UserResponseDto } from '@api';
|
||||
import type { SystemConfigStorageTemplateDto, SystemConfigTemplateStorageOptionDto, UserResponseDto } from '@api';
|
||||
import * as luxon from 'luxon';
|
||||
import handlebar from 'handlebars';
|
||||
import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import SupportedDatetimePanel from './supported-datetime-panel.svelte';
|
||||
import SupportedVariablesPanel from './supported-variables-panel.svelte';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import { isEqual } from 'lodash-es';
|
||||
|
@ -13,31 +10,20 @@
|
|||
NotificationType,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
save: SystemConfigStorageTemplateDto;
|
||||
}>();
|
||||
|
||||
export let storageConfig: SystemConfigStorageTemplateDto;
|
||||
export let storageDefault: SystemConfigStorageTemplateDto;
|
||||
export let user: UserResponseDto;
|
||||
export let disabled = false;
|
||||
export let templateOptions: SystemConfigTemplateStorageOptionDto;
|
||||
|
||||
let savedConfig: SystemConfigStorageTemplateDto;
|
||||
let defaultConfig: SystemConfigStorageTemplateDto;
|
||||
let templateOptions: SystemConfigTemplateStorageOptionDto;
|
||||
export let savedConfig: SystemConfigStorageTemplateDto;
|
||||
let selectedPreset = '';
|
||||
|
||||
async function getConfigs() {
|
||||
[savedConfig, defaultConfig, templateOptions] = await Promise.all([
|
||||
api.systemConfigApi.getConfig().then((res) => res.data.storageTemplate),
|
||||
api.systemConfigApi.getDefaults().then((res) => res.data.storageTemplate),
|
||||
api.systemConfigApi.getStorageTemplateOptions().then((res) => res.data),
|
||||
]);
|
||||
|
||||
selectedPreset = savedConfig.template;
|
||||
}
|
||||
|
||||
const getSupportDateTimeFormat = async () => {
|
||||
const { data } = await api.systemConfigApi.getStorageTemplateOptions();
|
||||
return data;
|
||||
};
|
||||
|
||||
$: parsedTemplate = () => {
|
||||
try {
|
||||
return renderTemplate(storageConfig.template);
|
||||
|
@ -77,48 +63,15 @@
|
|||
};
|
||||
|
||||
async function reset() {
|
||||
const { data: resetConfig } = await api.systemConfigApi.getConfig();
|
||||
|
||||
storageConfig.template = resetConfig.storageTemplate.template;
|
||||
savedConfig.template = resetConfig.storageTemplate.template;
|
||||
|
||||
storageConfig = { ...savedConfig };
|
||||
notificationController.show({
|
||||
message: 'Reset storage template settings to the recent saved settings',
|
||||
message: 'Reset storage template settings to the last saved settings',
|
||||
type: NotificationType.Info,
|
||||
});
|
||||
}
|
||||
|
||||
async function saveSetting() {
|
||||
try {
|
||||
const { data: currentConfig } = await api.systemConfigApi.getConfig();
|
||||
|
||||
const result = await api.systemConfigApi.updateConfig({
|
||||
systemConfigDto: {
|
||||
...currentConfig,
|
||||
storageTemplate: storageConfig,
|
||||
},
|
||||
});
|
||||
|
||||
storageConfig.template = result.data.storageTemplate.template;
|
||||
savedConfig.template = result.data.storageTemplate.template;
|
||||
|
||||
notificationController.show({
|
||||
message: 'Storage template saved',
|
||||
type: NotificationType.Info,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Error [storage-template-settings] [saveSetting]', e);
|
||||
notificationController.show({
|
||||
message: 'Unable to save settings',
|
||||
type: NotificationType.Error,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function resetToDefault() {
|
||||
const { data: defaultConfig } = await api.systemConfigApi.getDefaults();
|
||||
|
||||
storageConfig.template = defaultConfig.storageTemplate.template;
|
||||
storageConfig = { ...storageDefault };
|
||||
|
||||
notificationController.show({
|
||||
message: 'Reset storage template to default',
|
||||
|
@ -132,19 +85,10 @@
|
|||
</script>
|
||||
|
||||
<section class="dark:text-immich-dark-fg">
|
||||
{#await getConfigs() then}
|
||||
<div id="directory-path-builder" class="m-4">
|
||||
<h3 class="text-base font-medium text-immich-primary dark:text-immich-dark-primary">Variables</h3>
|
||||
|
||||
<section class="support-date">
|
||||
{#await getSupportDateTimeFormat()}
|
||||
<LoadingSpinner />
|
||||
{:then options}
|
||||
<div transition:fade={{ duration: 200 }}>
|
||||
<SupportedDatetimePanel {options} />
|
||||
</div>
|
||||
{/await}
|
||||
</section>
|
||||
<section class="support-date" />
|
||||
|
||||
<section class="support-date">
|
||||
<SupportedVariablesPanel />
|
||||
|
@ -158,8 +102,7 @@
|
|||
</div>
|
||||
|
||||
<p class="text-xs">
|
||||
Approximately path length limit : <span
|
||||
class="font-semibold text-immich-primary dark:text-immich-dark-primary"
|
||||
Approximately path length limit : <span class="font-semibold text-immich-primary dark:text-immich-dark-primary"
|
||||
>{parsedTemplate().length + user.id.length + 'UPLOAD_LOCATION'.length}</span
|
||||
>/260
|
||||
</p>
|
||||
|
@ -169,8 +112,7 @@
|
|||
</p>
|
||||
|
||||
<p class="mt-2 rounded-lg bg-gray-200 p-4 py-2 text-xs dark:bg-gray-700 dark:text-immich-dark-fg">
|
||||
<span class="text-immich-fg/25 dark:text-immich-dark-fg/50"
|
||||
>UPLOAD_LOCATION/{user.storageLabel || user.id}</span
|
||||
<span class="text-immich-fg/25 dark:text-immich-dark-fg/50">UPLOAD_LOCATION/{user.storageLabel || user.id}</span
|
||||
>/{parsedTemplate()}.jpg
|
||||
</p>
|
||||
|
||||
|
@ -179,7 +121,6 @@
|
|||
<label class="text-xs" for="preset-select">PRESET</label>
|
||||
<select
|
||||
class="mt-2 rounded-lg bg-slate-200 p-2 text-sm hover:cursor-pointer dark:bg-gray-600"
|
||||
{disabled}
|
||||
name="presets"
|
||||
id="preset-select"
|
||||
bind:value={selectedPreset}
|
||||
|
@ -193,7 +134,6 @@
|
|||
<div class="flex gap-2 align-bottom">
|
||||
<SettingInputField
|
||||
label="TEMPLATE"
|
||||
{disabled}
|
||||
required
|
||||
inputType={SettingInputFieldType.TEXT}
|
||||
bind:value={storageConfig.template}
|
||||
|
@ -216,13 +156,11 @@
|
|||
|
||||
<SettingButtonsRow
|
||||
on:reset={reset}
|
||||
on:save={saveSetting}
|
||||
on:save={() => dispatch('save', savedConfig)}
|
||||
on:reset-to-default={resetToDefault}
|
||||
showResetToDefault={!isEqual(savedConfig, defaultConfig)}
|
||||
{disabled}
|
||||
showResetToDefault={!isEqual(savedConfig, storageConfig)}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{/await}
|
||||
</section>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import SettingSelect from '$lib/components/admin-page/settings/setting-select.svelte';
|
||||
import { api, SystemConfigThumbnailDto } from '@api';
|
||||
import type { SystemConfigThumbnailDto } from '@api';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import SettingButtonsRow from '$lib/components/admin-page/settings/setting-buttons-row.svelte';
|
||||
|
@ -8,75 +8,38 @@
|
|||
notificationController,
|
||||
NotificationType,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
save: SystemConfigThumbnailDto;
|
||||
}>();
|
||||
|
||||
export let thumbnailConfig: SystemConfigThumbnailDto; // this is the config that is being edited
|
||||
export let thumbnailDefault: SystemConfigThumbnailDto;
|
||||
export let savedConfig: SystemConfigThumbnailDto;
|
||||
export let disabled = false;
|
||||
|
||||
let savedConfig: SystemConfigThumbnailDto;
|
||||
let defaultConfig: SystemConfigThumbnailDto;
|
||||
|
||||
async function getConfigs() {
|
||||
[savedConfig, defaultConfig] = await Promise.all([
|
||||
api.systemConfigApi.getConfig().then((res) => res.data.thumbnail),
|
||||
api.systemConfigApi.getDefaults().then((res) => res.data.thumbnail),
|
||||
]);
|
||||
}
|
||||
|
||||
async function reset() {
|
||||
const { data: resetConfig } = await api.systemConfigApi.getConfig();
|
||||
|
||||
thumbnailConfig = { ...resetConfig.thumbnail };
|
||||
savedConfig = { ...resetConfig.thumbnail };
|
||||
thumbnailConfig = { ...savedConfig };
|
||||
|
||||
notificationController.show({
|
||||
message: 'Reset thumbnail settings to the recent saved settings',
|
||||
message: 'Reset thumbnail settings to the last saved settings',
|
||||
type: NotificationType.Info,
|
||||
});
|
||||
}
|
||||
|
||||
async function resetToDefault() {
|
||||
const { data: configs } = await api.systemConfigApi.getDefaults();
|
||||
|
||||
thumbnailConfig = { ...configs.thumbnail };
|
||||
defaultConfig = { ...configs.thumbnail };
|
||||
thumbnailConfig = { ...thumbnailDefault };
|
||||
|
||||
notificationController.show({
|
||||
message: 'Reset thumbnail settings to default',
|
||||
type: NotificationType.Info,
|
||||
});
|
||||
}
|
||||
|
||||
async function saveSetting() {
|
||||
try {
|
||||
const { data: configs } = await api.systemConfigApi.getConfig();
|
||||
|
||||
const result = await api.systemConfigApi.updateConfig({
|
||||
systemConfigDto: {
|
||||
...configs,
|
||||
thumbnail: thumbnailConfig,
|
||||
},
|
||||
});
|
||||
|
||||
thumbnailConfig = { ...result.data.thumbnail };
|
||||
savedConfig = { ...result.data.thumbnail };
|
||||
|
||||
notificationController.show({
|
||||
message: 'Thumbnail settings saved',
|
||||
type: NotificationType.Info,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Error [thumbnail-settings] [saveSetting]', e);
|
||||
notificationController.show({
|
||||
message: 'Unable to save settings',
|
||||
type: NotificationType.Error,
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
{#await getConfigs() then}
|
||||
<div in:fade={{ duration: 500 }}>
|
||||
<div in:fade={{ duration: 300 }}>
|
||||
<form autocomplete="off" on:submit|preventDefault>
|
||||
<div class="ml-4 mt-4 flex flex-col gap-4">
|
||||
<SettingSelect
|
||||
|
@ -113,13 +76,12 @@
|
|||
<div class="ml-4">
|
||||
<SettingButtonsRow
|
||||
on:reset={reset}
|
||||
on:save={saveSetting}
|
||||
on:save={() => dispatch('save', thumbnailConfig)}
|
||||
on:reset-to-default={resetToDefault}
|
||||
showResetToDefault={!isEqual(savedConfig, defaultConfig)}
|
||||
showResetToDefault={!isEqual(thumbnailConfig, thumbnailDefault)}
|
||||
{disabled}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{/await}
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@ import { AppRoute } from '$lib/constants';
|
|||
import { redirect } from '@sveltejs/kit';
|
||||
import type { PageServerLoad } from './$types';
|
||||
|
||||
export const load: PageServerLoad = async ({ parent }) => {
|
||||
export const load: PageServerLoad = async ({ parent, locals }) => {
|
||||
const { user } = await parent();
|
||||
|
||||
if (!user) {
|
||||
|
@ -11,8 +11,14 @@ export const load: PageServerLoad = async ({ parent }) => {
|
|||
throw redirect(302, AppRoute.PHOTOS);
|
||||
}
|
||||
|
||||
const { data: config } = await locals.api.systemConfigApi.getConfig();
|
||||
const { data: defaultConfig } = await locals.api.systemConfigApi.getDefaults();
|
||||
const { data: templateOptions } = await locals.api.systemConfigApi.getStorageTemplateOptions();
|
||||
return {
|
||||
user,
|
||||
config,
|
||||
defaultConfig,
|
||||
templateOptions,
|
||||
meta: {
|
||||
title: 'System Settings',
|
||||
},
|
||||
|
|
|
@ -9,21 +9,46 @@
|
|||
import StorageTemplateSettings from '$lib/components/admin-page/settings/storage-template/storage-template-settings.svelte';
|
||||
import ThumbnailSettings from '$lib/components/admin-page/settings/thumbnail/thumbnail-settings.svelte';
|
||||
import Button from '$lib/components/elements/buttons/button.svelte';
|
||||
import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte';
|
||||
import { downloadManager } from '$lib/stores/download';
|
||||
import { featureFlags } from '$lib/stores/feature-flags.store';
|
||||
import { downloadBlob } from '$lib/utils/asset-utils';
|
||||
import { SystemConfigDto, api, copyToClipboard } from '@api';
|
||||
import { SystemConfigDto, SystemConfigTemplateStorageOptionDto, api, copyToClipboard } from '@api';
|
||||
import Alert from 'svelte-material-icons/Alert.svelte';
|
||||
import ContentCopy from 'svelte-material-icons/ContentCopy.svelte';
|
||||
import Download from 'svelte-material-icons/Download.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import {
|
||||
notificationController,
|
||||
NotificationType,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
export let data: PageData;
|
||||
let config: SystemConfigDto = data.config;
|
||||
|
||||
const getConfig = async () => {
|
||||
const { data } = await api.systemConfigApi.getConfig();
|
||||
return data;
|
||||
let currentConfig: SystemConfigDto = cloneDeep(config);
|
||||
let defaultConfig: SystemConfigDto = data.defaultConfig;
|
||||
let templateOptions: SystemConfigTemplateStorageOptionDto = data.templateOptions;
|
||||
|
||||
const handleSave = async (config: SystemConfigDto, settingsMessage: string) => {
|
||||
try {
|
||||
const { data } = await api.systemConfigApi.updateConfig({
|
||||
systemConfigDto: config,
|
||||
});
|
||||
|
||||
config = cloneDeep(data);
|
||||
currentConfig = cloneDeep(data);
|
||||
notificationController.show({
|
||||
message: `${settingsMessage} settings saved`,
|
||||
type: NotificationType.Info,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(`Error [${settingsMessage}-settings] [saveSetting]`, e);
|
||||
notificationController.show({
|
||||
message: 'Unable to save settings',
|
||||
type: NotificationType.Error,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const downloadConfig = (configs: SystemConfigDto) => {
|
||||
|
@ -42,62 +67,147 @@
|
|||
<h2 class="text-md text-immich-primary dark:text-immich-dark-primary">Config is currently set by a config file</h2>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<section class="">
|
||||
{#await getConfig()}
|
||||
<LoadingSpinner />
|
||||
{:then configs}
|
||||
<div class="flex justify-end gap-2">
|
||||
<Button size="sm" on:click={() => copyToClipboard(JSON.stringify(configs, null, 2))}>
|
||||
<div class="flex justify-end gap-2">
|
||||
<Button size="sm" on:click={() => copyToClipboard(JSON.stringify(config, null, 2))}>
|
||||
<ContentCopy size="18" />
|
||||
<span class="pl-2">Copy to Clipboard</span>
|
||||
</Button>
|
||||
<Button size="sm" on:click={() => downloadConfig(configs)}>
|
||||
<Button size="sm" on:click={() => downloadConfig(config)}>
|
||||
<Download size="18" />
|
||||
<span class="pl-2">Export as JSON</span>
|
||||
</Button>
|
||||
</div>
|
||||
<SettingAccordion title="Thumbnail Settings" subtitle="Manage the resolution of thumbnail sizes">
|
||||
<ThumbnailSettings disabled={$featureFlags.configFile} thumbnailConfig={configs.thumbnail} />
|
||||
</SettingAccordion>
|
||||
</div>
|
||||
<SettingAccordion title="Thumbnail Settings" subtitle="Manage the resolution of thumbnail sizes">
|
||||
<ThumbnailSettings
|
||||
bind:savedConfig={currentConfig.thumbnail}
|
||||
bind:thumbnailConfig={config.thumbnail}
|
||||
thumbnailDefault={defaultConfig.thumbnail}
|
||||
disabled={$featureFlags.configFile}
|
||||
on:save={({ detail: thumbnail }) => {
|
||||
handleSave(
|
||||
{
|
||||
...currentConfig,
|
||||
thumbnail,
|
||||
},
|
||||
'Thumbnail',
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</SettingAccordion>
|
||||
|
||||
<SettingAccordion
|
||||
title="FFmpeg Settings"
|
||||
subtitle="Manage the resolution and encoding information of the video files"
|
||||
>
|
||||
<FFmpegSettings disabled={$featureFlags.configFile} ffmpegConfig={configs.ffmpeg} />
|
||||
</SettingAccordion>
|
||||
<SettingAccordion title="FFmpeg Settings" subtitle="Manage the resolution and encoding information of the video files">
|
||||
<FFmpegSettings
|
||||
bind:savedConfig={currentConfig.ffmpeg}
|
||||
bind:ffmpegConfig={config.ffmpeg}
|
||||
ffmpegDefault={defaultConfig.ffmpeg}
|
||||
disabled={$featureFlags.configFile}
|
||||
on:save={({ detail: ffmpeg }) => {
|
||||
handleSave(
|
||||
{
|
||||
...currentConfig,
|
||||
ffmpeg,
|
||||
},
|
||||
'FFmpeg',
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</SettingAccordion>
|
||||
|
||||
<SettingAccordion title="Machine Learning Settings" subtitle="Manage model settings">
|
||||
<MachineLearningSettings disabled={$featureFlags.configFile} machineLearningConfig={configs.machineLearning} />
|
||||
</SettingAccordion>
|
||||
|
||||
<SettingAccordion
|
||||
<SettingAccordion
|
||||
title="Job Settings"
|
||||
subtitle="Manage job concurrency"
|
||||
isOpen={$page.url.searchParams.get('open') === 'job-settings'}
|
||||
>
|
||||
<JobSettings disabled={$featureFlags.configFile} jobConfig={configs.job} />
|
||||
</SettingAccordion>
|
||||
>
|
||||
<JobSettings
|
||||
bind:savedConfig={currentConfig.job}
|
||||
bind:jobConfig={config.job}
|
||||
jobDefault={defaultConfig.job}
|
||||
disabled={$featureFlags.configFile}
|
||||
on:save={({ detail: job }) => {
|
||||
handleSave(
|
||||
{
|
||||
...currentConfig,
|
||||
job,
|
||||
},
|
||||
'Job Settings',
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</SettingAccordion>
|
||||
|
||||
<SettingAccordion title="Password Authentication" subtitle="Manage login with password settings">
|
||||
<PasswordLoginSettings disabled={$featureFlags.configFile} passwordLoginConfig={configs.passwordLogin} />
|
||||
</SettingAccordion>
|
||||
<SettingAccordion title="Password Authentication" subtitle="Manage login with password settings">
|
||||
<PasswordLoginSettings
|
||||
bind:savedConfig={currentConfig.passwordLogin}
|
||||
bind:passwordLoginConfig={config.passwordLogin}
|
||||
bind:config
|
||||
disabled={$featureFlags.configFile}
|
||||
passwordLoginDefault={defaultConfig.passwordLogin}
|
||||
on:save={({ detail: passwordLogin }) => {
|
||||
handleSave(
|
||||
{
|
||||
...currentConfig,
|
||||
passwordLogin,
|
||||
},
|
||||
'Password Authentication',
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</SettingAccordion>
|
||||
<SettingAccordion title="Machine Learning" subtitle="Manage machine learning settings">
|
||||
<MachineLearningSettings
|
||||
bind:savedConfig={currentConfig.machineLearning}
|
||||
bind:machineLearningConfig={config.machineLearning}
|
||||
machineLearningDefault={defaultConfig.machineLearning}
|
||||
disabled={$featureFlags.configFile}
|
||||
on:save={({ detail: machineLearning }) => {
|
||||
handleSave(
|
||||
{
|
||||
...currentConfig,
|
||||
machineLearning,
|
||||
},
|
||||
'Machine Learning',
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</SettingAccordion>
|
||||
<SettingAccordion title="OAuth Authentication" subtitle="Manage the login with OAuth settings">
|
||||
<OAuthSettings
|
||||
bind:savedConfig={currentConfig.oauth}
|
||||
bind:oauthConfig={config.oauth}
|
||||
bind:config
|
||||
disabled={$featureFlags.configFile}
|
||||
oauthDefault={defaultConfig.oauth}
|
||||
on:save={({ detail: oauth }) => {
|
||||
handleSave(
|
||||
{
|
||||
...currentConfig,
|
||||
oauth,
|
||||
},
|
||||
'OAuth Authentication',
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</SettingAccordion>
|
||||
|
||||
<SettingAccordion title="OAuth Authentication" subtitle="Manage the login with OAuth settings">
|
||||
<OAuthSettings disabled={$featureFlags.configFile} oauthConfig={configs.oauth} />
|
||||
</SettingAccordion>
|
||||
|
||||
<SettingAccordion
|
||||
<SettingAccordion
|
||||
title="Storage Template"
|
||||
subtitle="Manage the folder structure and file name of the upload asset"
|
||||
isOpen={$page.url.searchParams.get('open') === 'storage-template'}
|
||||
>
|
||||
>
|
||||
<StorageTemplateSettings
|
||||
disabled={$featureFlags.configFile}
|
||||
storageConfig={configs.storageTemplate}
|
||||
savedConfig={currentConfig.storageTemplate}
|
||||
storageConfig={config.storageTemplate}
|
||||
user={data.user}
|
||||
storageDefault={defaultConfig.storageTemplate}
|
||||
{templateOptions}
|
||||
on:save={({ detail: storageTemplate }) => {
|
||||
handleSave(
|
||||
{
|
||||
...currentConfig,
|
||||
storageTemplate,
|
||||
},
|
||||
'Storage Template',
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</SettingAccordion>
|
||||
{/await}
|
||||
</section>
|
||||
</SettingAccordion>
|
||||
|
|
Loading…
Reference in a new issue