[skip ci] Update server settings for Authentication modes (#984)

* Update GQL interface

* Update queried server settings

* package.json: Fix GQL script

* Basic AuthMode setting

* Setting disable, disclaimer on login page

* Update gql generated files

* Alphabetical sort en.json

* Fix constants name typos

* Move settings types and constants to corresponding files

* Rename setting constants

* Update required server version

---------

Co-authored-by: schroda <50052685+schroda@users.noreply.github.com>
This commit is contained in:
Constantin Piber
2025-07-12 01:08:40 +02:00
committed by GitHub
parent cdee6f4efa
commit 0d288afe74
14 changed files with 338 additions and 204 deletions

View File

@@ -8,10 +8,16 @@
import { DEFAULT_DEVICE } from '@/modules/device/services/Device.ts';
import { DEFAULT_SORT_SETTINGS } from '@/modules/migration/Migration.constants.ts';
import { MetadataServerSettings } from '@/modules/settings/Settings.types.ts';
import { GlobalUpdateSkipEntriesSettings, MetadataServerSettings } from '@/modules/settings/Settings.types.ts';
import { GridLayout } from '@/modules/core/Core.types.ts';
import { getDefaultLanguages } from '@/modules/core/utils/Languages.ts';
import { ThemeMode } from '@/modules/theme/contexts/AppThemeContext.tsx';
import {
SelectSettingValue,
SelectSettingValueDisplayInfo,
} from '@/modules/core/components/settings/SelectSetting.tsx';
import { AuthMode, WebUiChannel, WebUiFlavor, WebUiInterface } from '@/lib/graphql/generated/graphql.ts';
import { TranslationKey } from '@/Base.types.ts';
export const MANGA_GRID_WIDTH = {
min: 100,
@@ -75,3 +81,109 @@ export const SERVER_SETTINGS_METADATA_DEFAULT: MetadataServerSettings = {
mangaDynamicColorSchemes: true,
mangaGridItemWidth: MANGA_GRID_WIDTH.default,
};
const AUTH_MODES = [AuthMode.None].concat(Object.values(AuthMode).filter((mode) => mode !== AuthMode.None));
const AUTH_MODES_TO_TRANSLATION_KEY: { [mode in AuthMode]: SelectSettingValueDisplayInfo } = {
[AuthMode.None]: {
text: 'settings.server.auth.mode.option.none.label.title',
description: 'settings.server.auth.mode.option.none.label.description',
disclaimer: 'settings.server.auth.mode.option.none.label.info',
},
[AuthMode.BasicAuth]: {
text: 'settings.server.auth.mode.option.basicAuth.label.title',
description: 'settings.server.auth.mode.option.basicAuth.label.description',
},
[AuthMode.SimpleLogin]: {
text: 'settings.server.auth.mode.option.simpleLogin.label.title',
description: 'settings.server.auth.mode.option.simpleLogin.label.description',
disclaimer: 'settings.server.auth.mode.option.simpleLogin.label.info',
},
};
export const AUTH_MODES_SELECT_VALUES: SelectSettingValue<AuthMode>[] = AUTH_MODES.map((mode) => [
mode,
AUTH_MODES_TO_TRANSLATION_KEY[mode],
]);
const WEB_UI_FLAVORS = Object.values(WebUiFlavor);
const WEB_UI_FLAVOR_TO_TRANSLATION_KEY: { [flavor in WebUiFlavor]: SelectSettingValueDisplayInfo } = {
[WebUiFlavor.Webui]: {
text: 'settings.webui.title.webui',
description: 'settings.webui.flavor.option.webui.label.description',
disclaimer: 'settings.webui.flavor.label.info',
},
[WebUiFlavor.Vui]: {
text: 'settings.webui.flavor.option.vui.label.title',
description: 'settings.webui.flavor.option.vui.label.description',
disclaimer: 'settings.webui.flavor.label.info',
},
[WebUiFlavor.Custom]: {
text: 'settings.webui.flavor.option.custom.label.title',
description: 'settings.webui.flavor.option.custom.label.description',
},
};
export const WEB_UI_FLAVOR_SELECT_VALUES: SelectSettingValue<WebUiFlavor>[] = WEB_UI_FLAVORS.map((flavor) => [
flavor,
WEB_UI_FLAVOR_TO_TRANSLATION_KEY[flavor],
]);
const WEB_UI_CHANNELS = Object.values(WebUiChannel);
const WEB_UI_CHANNEL_TO_TRANSLATION_KEYS: {
[channel in WebUiChannel]: SelectSettingValueDisplayInfo;
} = {
[WebUiChannel.Bundled]: {
text: 'settings.webui.channel.option.bundled.label.title',
description: 'settings.webui.channel.option.bundled.label.description',
disclaimer: 'settings.webui.flavor.label.info',
},
[WebUiChannel.Stable]: {
text: 'settings.webui.channel.option.stable.label.title',
description: 'settings.webui.channel.option.stable.label.description',
disclaimer: 'settings.webui.flavor.label.info',
},
[WebUiChannel.Preview]: {
text: 'settings.webui.channel.option.preview.label.title',
description: 'settings.webui.channel.option.preview.label.description',
disclaimer: 'settings.webui.channel.option.preview.label.disclaimer',
},
};
export const WEB_UI_CHANNEL_SELECT_VALUES: SelectSettingValue<WebUiChannel>[] = WEB_UI_CHANNELS.map((channel) => [
channel,
WEB_UI_CHANNEL_TO_TRANSLATION_KEYS[channel],
]);
const WEB_UI_INTERFACES = Object.values(WebUiInterface);
const WEB_UI_INTERFACE_TO_TRANSLATION_KEYS: {
[webUIInterface in WebUiInterface]: SelectSettingValueDisplayInfo;
} = {
[WebUiInterface.Browser]: {
text: 'settings.webui.interface.option.label.browser',
description: 'settings.webui.interface.label.description',
},
[WebUiInterface.Electron]: {
text: 'settings.webui.interface.option.label.electron',
description: 'settings.webui.interface.label.description',
},
};
export const WEB_UI_INTERFACE_SELECT_VALUES: SelectSettingValue<WebUiInterface>[] = WEB_UI_INTERFACES.map(
(webUIInterface) => [webUIInterface, WEB_UI_INTERFACE_TO_TRANSLATION_KEYS[webUIInterface]],
);
export const GLOBAL_UPDATE_INTERVAL = {
default: 12,
min: 6,
max: 24 * 7 * 4, // 1 month
};
export const GLOBAL_UPDATE_SKIP_ENTRIES_TO_TRANSLATION: {
[setting in keyof GlobalUpdateSkipEntriesSettings]: TranslationKey;
} = {
excludeUnreadChapters: 'library.settings.global_update.entries.label.unread_chapters',
excludeNotStarted: 'library.settings.global_update.entries.label.not_started',
excludeCompleted: 'library.settings.global_update.entries.label.completed',
};
export const WEB_UI_UPDATE_INTERVAL = {
default: 23,
min: 1,
max: 23,
};

View File

@@ -16,6 +16,7 @@ import { MetadataUpdateSettings } from '@/modules/app-updates/AppUpdateChecker.t
import { MetadataThemeSettings } from '@/modules/theme/AppTheme.types.ts';
import { GetServerSettingsQuery } from '@/lib/graphql/generated/graphql.ts';
import { MetadataHistorySettings } from '@/modules/history/History.types.ts';
import { ServerSettings as GqlServerSettings } from '@/modules/settings/Settings.types.ts';
export type MetadataServerSettingKeys = keyof MetadataServerSettings;
@@ -36,3 +37,52 @@ export interface ISearchSettings {
}
export type ServerSettings = Omit<GetServerSettingsQuery['settings'], '__typename'>;
export type ServerSettingsType = Pick<
GqlServerSettings,
| 'ip'
| 'port'
| 'socksProxyEnabled'
| 'socksProxyVersion'
| 'socksProxyHost'
| 'socksProxyPort'
| 'socksProxyUsername'
| 'socksProxyPassword'
| 'debugLogsEnabled'
| 'systemTrayEnabled'
| 'maxLogFiles'
| 'maxLogFileSize'
| 'maxLogFolderSize'
| 'authMode'
| 'authUsername'
| 'authPassword'
| 'flareSolverrEnabled'
| 'flareSolverrTimeout'
| 'flareSolverrUrl'
| 'flareSolverrSessionName'
| 'flareSolverrSessionTtl'
| 'flareSolverrAsResponseFallback'
| 'opdsUseBinaryFileSizes'
| 'opdsItemsPerPage'
| 'opdsEnablePageReadProgress'
| 'opdsMarkAsReadOnDownload'
| 'opdsShowOnlyUnreadChapters'
| 'opdsShowOnlyDownloadedChapters'
| 'opdsChapterSortOrder'
>;
export type WebUISettingsType = Pick<
ServerSettings,
| 'webUIFlavor'
| 'initialOpenInBrowserEnabled'
| 'webUIInterface'
| 'electronPath'
| 'webUIChannel'
| 'webUIUpdateCheckInterval'
>;
export type GlobalUpdateSkipEntriesSettings = Pick<
ServerSettings,
'excludeUnreadChapters' | 'excludeNotStarted' | 'excludeCompleted'
>;
export type LibrarySettingsType = Pick<ServerSettings, 'updateMangas'>;

View File

@@ -20,11 +20,9 @@ import { GlobalUpdateSettingsEntries } from '@/modules/settings/components/globa
import { GlobalUpdateSettingsInterval } from '@/modules/settings/components/globalUpdate/GlobalUpdateSettingsInterval.tsx';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import { makeToast } from '@/modules/core/utils/Toast.ts';
import { ServerSettings } from '@/modules/settings/Settings.types.ts';
import { LibrarySettingsType, ServerSettings } from '@/modules/settings/Settings.types.ts';
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
type LibrarySettingsType = Pick<ServerSettings, 'updateMangas'>;
export const GlobalUpdateSettings = ({
serverSettings,
categories,

View File

@@ -20,34 +20,23 @@ import { requestManager } from '@/lib/requests/RequestManager.ts';
import { makeToast } from '@/modules/core/utils/Toast.ts';
import { CheckboxContainer } from '@/modules/core/components/inputs/CheckboxContainer.ts';
import { CheckboxInput } from '@/modules/core/components/inputs/CheckboxInput.tsx';
import { TranslationKey } from '@/Base.types.ts';
import { ServerSettings } from '@/modules/settings/Settings.types.ts';
import { GlobalUpdateSkipEntriesSettings, ServerSettings } from '@/modules/settings/Settings.types.ts';
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
type GlobalUpdateSkipEntriesSettings = Pick<
ServerSettings,
'excludeUnreadChapters' | 'excludeNotStarted' | 'excludeCompleted'
>;
const settingToTextMap: { [setting in keyof GlobalUpdateSkipEntriesSettings]: TranslationKey } = {
excludeUnreadChapters: 'library.settings.global_update.entries.label.unread_chapters',
excludeNotStarted: 'library.settings.global_update.entries.label.not_started',
excludeCompleted: 'library.settings.global_update.entries.label.completed',
};
import { GLOBAL_UPDATE_SKIP_ENTRIES_TO_TRANSLATION } from '@/modules/settings/Settings.constants.ts';
const getSkipMangasText = (settings: GlobalUpdateSkipEntriesSettings) => {
const skipSettings: string[] = [];
if (settings.excludeUnreadChapters) {
skipSettings.push(translate(settingToTextMap.excludeUnreadChapters) as string);
skipSettings.push(translate(GLOBAL_UPDATE_SKIP_ENTRIES_TO_TRANSLATION.excludeUnreadChapters) as string);
}
if (settings.excludeNotStarted) {
skipSettings.push(translate(settingToTextMap.excludeNotStarted) as string);
skipSettings.push(translate(GLOBAL_UPDATE_SKIP_ENTRIES_TO_TRANSLATION.excludeNotStarted) as string);
}
if (settings.excludeCompleted) {
skipSettings.push(translate(settingToTextMap.excludeCompleted) as string);
skipSettings.push(translate(GLOBAL_UPDATE_SKIP_ENTRIES_TO_TRANSLATION.excludeCompleted) as string);
}
const isNothingExcluded = !skipSettings.length;
@@ -132,7 +121,11 @@ export const GlobalUpdateSettingsEntries = ({ serverSettings }: { serverSettings
{Object.entries(dialogSettings).map(([setting, value]) => (
<CheckboxInput
key={setting}
label={t(settingToTextMap[setting as keyof GlobalUpdateSkipEntriesSettings])}
label={t(
GLOBAL_UPDATE_SKIP_ENTRIES_TO_TRANSLATION[
setting as keyof GlobalUpdateSkipEntriesSettings
],
)}
checked={value}
onChange={(_, checked) => {
setDialogSettings({

View File

@@ -17,10 +17,7 @@ import { NumberSetting } from '@/modules/core/components/settings/NumberSetting.
import { getPersistedServerSetting, usePersistedValue } from '@/modules/core/hooks/usePersistedValue.tsx';
import { ServerSettings } from '@/modules/settings/Settings.types.ts';
const DEFAULT_INTERVAL_HOURS = 12;
const MIN_INTERVAL_HOURS = 6;
const MAX_INTERVAL_HOURS = 24 * 7 * 4; // 1 month
import { GLOBAL_UPDATE_INTERVAL } from '@/modules/settings/Settings.constants.ts';
export const GlobalUpdateSettingsInterval = ({
globalUpdateInterval,
@@ -34,7 +31,7 @@ export const GlobalUpdateSettingsInterval = ({
const [mutateSettings] = requestManager.useUpdateServerSettings();
const [currentAutoUpdateIntervalHours, persistAutoUpdateIntervalHours] = usePersistedValue(
'lastGlobalUpdateInterval',
DEFAULT_INTERVAL_HOURS,
GLOBAL_UPDATE_INTERVAL.default,
autoUpdateIntervalHours,
getPersistedServerSetting,
);
@@ -66,9 +63,9 @@ export const GlobalUpdateSettingsInterval = ({
hours: currentAutoUpdateIntervalHours,
})}
value={currentAutoUpdateIntervalHours}
minValue={MIN_INTERVAL_HOURS}
maxValue={MAX_INTERVAL_HOURS}
defaultValue={DEFAULT_INTERVAL_HOURS}
minValue={GLOBAL_UPDATE_INTERVAL.min}
maxValue={GLOBAL_UPDATE_INTERVAL.max}
defaultValue={GLOBAL_UPDATE_INTERVAL.default}
showSlider
valueUnit={t('global.time.hour_short')}
handleUpdate={updateSetting}

View File

@@ -18,10 +18,7 @@ import { getPersistedServerSetting, usePersistedValue } from '@/modules/core/hoo
import { makeToast } from '@/modules/core/utils/Toast.ts';
import { ServerSettings } from '@/modules/settings/Settings.types.ts';
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
const DEFAULT_VALUE = 23;
const MIN_VALUE = 1;
const MAX_VALUE = 23; // 1 month
import { WEB_UI_UPDATE_INTERVAL } from '@/modules/settings/Settings.constants.ts';
export const WebUIUpdateIntervalSetting = ({
disabled = false,
@@ -36,7 +33,7 @@ export const WebUIUpdateIntervalSetting = ({
const [mutateSettings] = requestManager.useUpdateServerSettings();
const [currentUpdateCheckInterval, persistUpdateCheckInterval] = usePersistedValue(
'lastUpdateCheckInterval',
DEFAULT_VALUE,
WEB_UI_UPDATE_INTERVAL.default,
updateCheckInterval,
getPersistedServerSetting,
);
@@ -75,9 +72,9 @@ export const WebUIUpdateIntervalSetting = ({
hours: currentUpdateCheckInterval,
})}
value={currentUpdateCheckInterval}
minValue={MIN_VALUE}
maxValue={MAX_VALUE}
defaultValue={DEFAULT_VALUE}
minValue={WEB_UI_UPDATE_INTERVAL.min}
maxValue={WEB_UI_UPDATE_INTERVAL.max}
defaultValue={WEB_UI_UPDATE_INTERVAL.default}
showSlider
valueUnit={t('global.time.hour_short')}
handleUpdate={updateSetting}

View File

@@ -6,7 +6,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { useTranslation, Trans } from 'react-i18next';
import { Trans, useTranslation } from 'react-i18next';
import { useMemo } from 'react';
import Link from '@mui/material/Link';
import List from '@mui/material/List';
@@ -29,43 +29,11 @@ import {
} from '@/modules/settings/services/ServerSettingsMetadata.ts';
import { makeToast } from '@/modules/core/utils/Toast.ts';
import { MetadataUpdateSettings } from '@/modules/app-updates/AppUpdateChecker.types.ts';
import { ServerSettings as GqlServerSettings } from '@/modules/settings/Settings.types.ts';
import { ServerSettings as GqlServerSettings, ServerSettingsType } from '@/modules/settings/Settings.types.ts';
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
import { useAppTitle } from '@/modules/navigation-bar/hooks/useAppTitle.ts';
import { SortOrder } from '@/lib/graphql/generated/graphql';
type ServerSettingsType = Pick<
GqlServerSettings,
| 'ip'
| 'port'
| 'socksProxyEnabled'
| 'socksProxyVersion'
| 'socksProxyHost'
| 'socksProxyPort'
| 'socksProxyUsername'
| 'socksProxyPassword'
| 'debugLogsEnabled'
| 'systemTrayEnabled'
| 'maxLogFiles'
| 'maxLogFileSize'
| 'maxLogFolderSize'
| 'basicAuthEnabled'
| 'basicAuthUsername'
| 'basicAuthPassword'
| 'flareSolverrEnabled'
| 'flareSolverrTimeout'
| 'flareSolverrUrl'
| 'flareSolverrSessionName'
| 'flareSolverrSessionTtl'
| 'flareSolverrAsResponseFallback'
| 'opdsUseBinaryFileSizes'
| 'opdsItemsPerPage'
| 'opdsEnablePageReadProgress'
| 'opdsMarkAsReadOnDownload'
| 'opdsShowOnlyUnreadChapters'
| 'opdsShowOnlyDownloadedChapters'
| 'opdsChapterSortOrder'
>;
import { AuthMode, SortOrder } from '@/lib/graphql/generated/graphql';
import { AUTH_MODES_SELECT_VALUES } from '@/modules/settings/Settings.constants.ts';
const extractServerSettings = (settings: GqlServerSettings): ServerSettingsType => ({
ip: settings.ip,
@@ -81,9 +49,9 @@ const extractServerSettings = (settings: GqlServerSettings): ServerSettingsType
maxLogFiles: settings.maxLogFiles,
maxLogFileSize: settings.maxLogFileSize,
maxLogFolderSize: settings.maxLogFolderSize,
basicAuthEnabled: settings.basicAuthEnabled,
basicAuthUsername: settings.basicAuthUsername,
basicAuthPassword: settings.basicAuthPassword,
authMode: settings.authMode,
authUsername: settings.authUsername,
authPassword: settings.authPassword,
flareSolverrEnabled: settings.flareSolverrEnabled,
flareSolverrTimeout: settings.flareSolverrTimeout,
flareSolverrUrl: settings.flareSolverrUrl,
@@ -216,6 +184,7 @@ export const ServerSettings = () => {
}
const serverSettings = extractServerSettings(data!.settings);
const authModeDisabled = !serverSettings.authUsername.trim() || !serverSettings.authPassword.trim();
return (
<List sx={{ pt: 0 }}>
@@ -295,27 +264,25 @@ export const ServerSettings = () => {
</ListSubheader>
}
>
<ListItem>
<ListItemText primary={t('settings.server.auth.basic.label.enable')} />
<Switch
edge="end"
checked={serverSettings.basicAuthEnabled}
disabled={!serverSettings.basicAuthUsername.trim() && !serverSettings.basicAuthPassword.trim()}
onChange={(e) => updateSetting('basicAuthEnabled', e.target.checked)}
/>
</ListItem>
<TextSetting
settingName={t('settings.server.auth.basic.label.username')}
value={serverSettings.basicAuthUsername}
validate={(value) => !serverSettings.basicAuthEnabled || !!value.trim()}
handleChange={(authUsername) => updateSetting('basicAuthUsername', authUsername)}
<SelectSetting<AuthMode>
settingName={t('settings.server.auth.label.title')}
value={serverSettings.authMode}
values={AUTH_MODES_SELECT_VALUES}
handleChange={(mode) => updateSetting('authMode', mode)}
disabled={authModeDisabled}
/>
<TextSetting
settingName={t('settings.server.auth.basic.label.password')}
value={serverSettings.basicAuthPassword}
settingName={t('settings.server.auth.label.username')}
value={serverSettings.authUsername}
validate={(value) => serverSettings.authMode === AuthMode.None || !!value.trim()}
handleChange={(authUsername) => updateSetting('authUsername', authUsername)}
/>
<TextSetting
settingName={t('settings.server.auth.label.password')}
value={serverSettings.authPassword}
isPassword
validate={(value) => !serverSettings.basicAuthEnabled || !!value.trim()}
handleChange={(authPassword) => updateSetting('basicAuthPassword', authPassword)}
validate={(value) => serverSettings.authMode === AuthMode.None || !!value.trim()}
handleChange={(authPassword) => updateSetting('authPassword', authPassword)}
/>
</List>
<List

View File

@@ -14,11 +14,7 @@ import Switch from '@mui/material/Switch';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import { WebUIUpdateIntervalSetting } from '@/modules/settings/components/webUI/WebUIUpdateIntervalSetting.tsx';
import { TextSetting } from '@/modules/core/components/settings/text/TextSetting.tsx';
import {
SelectSetting,
SelectSettingValue,
SelectSettingValueDisplayInfo,
} from '@/modules/core/components/settings/SelectSetting.tsx';
import { SelectSetting } from '@/modules/core/components/settings/SelectSetting.tsx';
import { WebUiChannel, WebUiFlavor, WebUiInterface } from '@/lib/graphql/generated/graphql.ts';
import { LoadingPlaceholder } from '@/modules/core/components/feedback/LoadingPlaceholder.tsx';
import { EmptyViewAbsoluteCentered } from '@/modules/core/components/feedback/EmptyViewAbsoluteCentered.tsx';
@@ -29,84 +25,14 @@ import {
} from '@/modules/settings/services/ServerSettingsMetadata.ts';
import { makeToast } from '@/modules/core/utils/Toast.ts';
import { MetadataUpdateSettings } from '@/modules/app-updates/AppUpdateChecker.types.ts';
import { ServerSettings } from '@/modules/settings/Settings.types.ts';
import { ServerSettings, WebUISettingsType } from '@/modules/settings/Settings.types.ts';
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
import { useAppTitle } from '@/modules/navigation-bar/hooks/useAppTitle.ts';
type WebUISettingsType = Pick<
ServerSettings,
| 'webUIFlavor'
| 'initialOpenInBrowserEnabled'
| 'webUIInterface'
| 'electronPath'
| 'webUIChannel'
| 'webUIUpdateCheckInterval'
>;
const FLAVORS = Object.values(WebUiFlavor);
const FLAVOR_TO_TRANSLATION_KEY: { [flavor in WebUiFlavor]: SelectSettingValueDisplayInfo } = {
[WebUiFlavor.Webui]: {
text: 'settings.webui.title.webui',
description: 'settings.webui.flavor.option.webui.label.description',
disclaimer: 'settings.webui.flavor.label.info',
},
[WebUiFlavor.Vui]: {
text: 'settings.webui.flavor.option.vui.label.title',
description: 'settings.webui.flavor.option.vui.label.description',
disclaimer: 'settings.webui.flavor.label.info',
},
[WebUiFlavor.Custom]: {
text: 'settings.webui.flavor.option.custom.label.title',
description: 'settings.webui.flavor.option.custom.label.description',
},
};
const FLAVOR_SELECT_VALUES: SelectSettingValue<WebUiFlavor>[] = FLAVORS.map((flavor) => [
flavor,
FLAVOR_TO_TRANSLATION_KEY[flavor],
]);
const CHANNELS = Object.values(WebUiChannel);
const CHANNEL_TO_TRANSLATION_KEYS: {
[channel in WebUiChannel]: SelectSettingValueDisplayInfo;
} = {
[WebUiChannel.Bundled]: {
text: 'settings.webui.channel.option.bundled.label.title',
description: 'settings.webui.channel.option.bundled.label.description',
disclaimer: 'settings.webui.flavor.label.info',
},
[WebUiChannel.Stable]: {
text: 'settings.webui.channel.option.stable.label.title',
description: 'settings.webui.channel.option.stable.label.description',
disclaimer: 'settings.webui.flavor.label.info',
},
[WebUiChannel.Preview]: {
text: 'settings.webui.channel.option.preview.label.title',
description: 'settings.webui.channel.option.preview.label.description',
disclaimer: 'settings.webui.channel.option.preview.label.disclaimer',
},
};
const CHANNEL_SELECT_VALUES: SelectSettingValue<WebUiChannel>[] = CHANNELS.map((channel) => [
channel,
CHANNEL_TO_TRANSLATION_KEYS[channel],
]);
const INTERFACES = Object.values(WebUiInterface);
const INTERFACE_TO_TRANSLATION_KEYS: {
[webUIInterface in WebUiInterface]: SelectSettingValueDisplayInfo;
} = {
[WebUiInterface.Browser]: {
text: 'settings.webui.interface.option.label.browser',
description: 'settings.webui.interface.label.description',
},
[WebUiInterface.Electron]: {
text: 'settings.webui.interface.option.label.electron',
description: 'settings.webui.interface.label.description',
},
};
const INTERFACE_SELECT_VALUES: SelectSettingValue<WebUiInterface>[] = INTERFACES.map((webUIInterface) => [
webUIInterface,
INTERFACE_TO_TRANSLATION_KEYS[webUIInterface],
]);
import {
WEB_UI_CHANNEL_SELECT_VALUES,
WEB_UI_FLAVOR_SELECT_VALUES,
WEB_UI_INTERFACE_SELECT_VALUES,
} from '@/modules/settings/Settings.constants.ts';
const extractWebUISettings = (settings: ServerSettings): WebUISettingsType => ({
webUIFlavor: settings.webUIFlavor,
@@ -190,7 +116,7 @@ export const WebUISettings = () => {
<SelectSetting<WebUiFlavor>
settingName={t('settings.webui.flavor.label.title')}
value={webUISettings.webUIFlavor}
values={FLAVOR_SELECT_VALUES}
values={WEB_UI_FLAVOR_SELECT_VALUES}
handleChange={(flavor) => updateSetting('webUIFlavor', flavor)}
/>
<ListItem>
@@ -204,7 +130,7 @@ export const WebUISettings = () => {
<SelectSetting<WebUiInterface>
settingName={t('settings.webui.interface.label.title')}
value={webUISettings.webUIInterface}
values={INTERFACE_SELECT_VALUES}
values={WEB_UI_INTERFACE_SELECT_VALUES}
handleChange={(webUIInterface) => updateSetting('webUIInterface', webUIInterface)}
/>
<TextSetting
@@ -219,7 +145,7 @@ export const WebUISettings = () => {
<SelectSetting<WebUiChannel>
settingName={t('settings.webui.channel.label.title')}
value={webUISettings.webUIChannel}
values={CHANNEL_SELECT_VALUES}
values={WEB_UI_CHANNEL_SELECT_VALUES}
handleChange={(channel) => updateSetting('webUIChannel', channel)}
disabled={isCustomWebUI}
/>