mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-03 19:17:13 -05:00 
			
		
		
		
	Use password and select config fields
This commit is contained in:
		
							parent
							
								
									f5fc04cfe2
								
							
						
					
					
						commit
						9f8b8a9f20
					
				@ -35,6 +35,7 @@
 | 
			
		||||
                                                    @case (ConfigOptionType.String) { <pngx-input-text [formControlName]="option.key" [error]="errors[option.key]"></pngx-input-text> }
 | 
			
		||||
                                                    @case (ConfigOptionType.JSON) { <pngx-input-text [formControlName]="option.key" [error]="errors[option.key]"></pngx-input-text> }
 | 
			
		||||
                                                    @case (ConfigOptionType.File) { <pngx-input-file [formControlName]="option.key" (upload)="uploadFile($event, option.key)" [error]="errors[option.key]"></pngx-input-file> }
 | 
			
		||||
                                                    @case (ConfigOptionType.Password) { <pngx-input-password [formControlName]="option.key" [error]="errors[option.key]"></pngx-input-password> }
 | 
			
		||||
                                                }
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,11 @@
 | 
			
		||||
<div class="mb-3">
 | 
			
		||||
  <label class="form-label" [for]="inputId">{{title}}</label>
 | 
			
		||||
<div class="mb-3" [class.pb-3]="error">
 | 
			
		||||
  <div class="row">
 | 
			
		||||
    <div class="d-flex align-items-center position-relative hidden-button-container" [class.col-md-3]="horizontal">
 | 
			
		||||
      @if (title) {
 | 
			
		||||
        <label class="form-label" [class.mb-md-0]="horizontal" [for]="inputId">{{title}}</label>
 | 
			
		||||
      }
 | 
			
		||||
    </div>
 | 
			
		||||
  <div class="position-relative" [class.col-md-9]="horizontal">
 | 
			
		||||
    <div class="input-group" [class.is-invalid]="error">
 | 
			
		||||
      <input #inputField [type]="showReveal && textVisible ? 'text' : 'password'" class="form-control" [class.is-invalid]="error" [id]="inputId" [(ngModel)]="value" (focus)="onFocus()" (focusout)="onFocusOut()" (change)="onChange(value)" [disabled]="disabled" [autocomplete]="autocomplete">
 | 
			
		||||
      @if (showReveal) {
 | 
			
		||||
@ -14,4 +20,5 @@
 | 
			
		||||
    @if (hint) {
 | 
			
		||||
      <small class="form-text text-muted" [innerHTML]="hint | safeHtml"></small>
 | 
			
		||||
    }
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user