From 2b608f19e45c8eeb33f00c719602c48bb3b177d5 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu, 24 Apr 2025 13:54:42 -0700 Subject: [PATCH] Use password and select config fields --- .../admin/config/config.component.html | 1 + .../admin/config/config.component.ts | 2 ++ .../input/password/password.component.html | 35 +++++++++++-------- src-ui/src/app/data/paperless-config.ts | 11 ++++-- src/paperless/serialisers.py | 4 +++ 5 files changed, 37 insertions(+), 16 deletions(-) diff --git a/src-ui/src/app/components/admin/config/config.component.html b/src-ui/src/app/components/admin/config/config.component.html index 0f74339fb..ca1cc9e44 100644 --- a/src-ui/src/app/components/admin/config/config.component.html +++ b/src-ui/src/app/components/admin/config/config.component.html @@ -35,6 +35,7 @@ @case (ConfigOptionType.String) { } @case (ConfigOptionType.JSON) { } @case (ConfigOptionType.File) { } + @case (ConfigOptionType.Password) { } } diff --git a/src-ui/src/app/components/admin/config/config.component.ts b/src-ui/src/app/components/admin/config/config.component.ts index 76f6b8795..767c084b1 100644 --- a/src-ui/src/app/components/admin/config/config.component.ts +++ b/src-ui/src/app/components/admin/config/config.component.ts @@ -29,6 +29,7 @@ import { SettingsService } from 'src/app/services/settings.service' import { ToastService } from 'src/app/services/toast.service' import { FileComponent } from '../../common/input/file/file.component' import { NumberComponent } from '../../common/input/number/number.component' +import { PasswordComponent } from '../../common/input/password/password.component' import { SelectComponent } from '../../common/input/select/select.component' import { SwitchComponent } from '../../common/input/switch/switch.component' import { TextComponent } from '../../common/input/text/text.component' @@ -46,6 +47,7 @@ import { LoadingComponentWithPermissions } from '../../loading-component/loading TextComponent, NumberComponent, FileComponent, + PasswordComponent, AsyncPipe, NgbNavModule, FormsModule, diff --git a/src-ui/src/app/components/common/input/password/password.component.html b/src-ui/src/app/components/common/input/password/password.component.html index 1a70ff4f6..6b8ae75cd 100644 --- a/src-ui/src/app/components/common/input/password/password.component.html +++ b/src-ui/src/app/components/common/input/password/password.component.html @@ -1,17 +1,24 @@ -
- -
- - @if (showReveal) { - +
+
+
+ @if (title) { + + } +
+
+
+ + @if (showReveal) { + + } +
+
+ {{error}} +
+ @if (hint) { + }
-
- {{error}} -
- @if (hint) { - - }
diff --git a/src-ui/src/app/data/paperless-config.ts b/src-ui/src/app/data/paperless-config.ts index 1d8f27b33..eea134692 100644 --- a/src-ui/src/app/data/paperless-config.ts +++ b/src-ui/src/app/data/paperless-config.ts @@ -44,6 +44,7 @@ export enum ConfigOptionType { Boolean = 'boolean', JSON = 'json', File = 'file', + Password = 'password', } export const ConfigCategory = { @@ -53,6 +54,11 @@ export const ConfigCategory = { AI: $localize`AI Settings`, } +export const LLMBackendConfig = { + OPENAI: 'openai', + OLLAMA: 'ollama', +} + export interface ConfigOption { key: string title: string @@ -267,7 +273,8 @@ export const PaperlessConfigOptions: ConfigOption[] = [ { key: 'llm_backend', title: $localize`LLM Backend`, - type: ConfigOptionType.String, + type: ConfigOptionType.Select, + choices: mapToItems(LLMBackendConfig), config_key: 'PAPERLESS_LLM_BACKEND', category: ConfigCategory.AI, }, @@ -281,7 +288,7 @@ export const PaperlessConfigOptions: ConfigOption[] = [ { key: 'llm_api_key', title: $localize`LLM API Key`, - type: ConfigOptionType.String, + type: ConfigOptionType.Password, config_key: 'PAPERLESS_LLM_API_KEY', category: ConfigCategory.AI, }, diff --git a/src/paperless/serialisers.py b/src/paperless/serialisers.py index 9943a76ee..716b72a8a 100644 --- a/src/paperless/serialisers.py +++ b/src/paperless/serialisers.py @@ -190,6 +190,10 @@ class ProfileSerializer(serializers.ModelSerializer): class ApplicationConfigurationSerializer(serializers.ModelSerializer): user_args = serializers.JSONField(binary=True, allow_null=True) barcode_tag_mapping = serializers.JSONField(binary=True, allow_null=True) + llm_api_key = ObfuscatedPasswordField( + required=False, + allow_null=True, + ) def run_validation(self, data): # Empty strings treated as None to avoid unexpected behavior