Fully dynamic config form
This commit is contained in:
parent
cf0dc73eb3
commit
d7067dc355
@ -29,6 +29,7 @@
|
|||||||
@case (ConfigOptionType.Number) { <pngx-input-number [formControlName]="option.key" [error]="errors[option.key]" [showAdd]="false"></pngx-input-number> }
|
@case (ConfigOptionType.Number) { <pngx-input-number [formControlName]="option.key" [error]="errors[option.key]" [showAdd]="false"></pngx-input-number> }
|
||||||
@case (ConfigOptionType.Boolean) { <pngx-input-switch [formControlName]="option.key" [error]="errors[option.key]" title="Enable" i18n-title></pngx-input-switch> }
|
@case (ConfigOptionType.Boolean) { <pngx-input-switch [formControlName]="option.key" [error]="errors[option.key]" title="Enable" i18n-title></pngx-input-switch> }
|
||||||
@case (ConfigOptionType.String) { <pngx-input-text [formControlName]="option.key" [error]="errors[option.key]"></pngx-input-text> }
|
@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> }
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -87,7 +87,7 @@ describe('ConfigComponent', () => {
|
|||||||
|
|
||||||
it('should support discard changes', () => {
|
it('should support discard changes', () => {
|
||||||
component.initialConfig = { output_type: OutputTypeConfig.PDF_A2 } as any
|
component.initialConfig = { output_type: OutputTypeConfig.PDF_A2 } as any
|
||||||
component.configForm.get('output_type').patchValue(OutputTypeConfig.PDF_A)
|
component.configForm.patchValue({ output_type: OutputTypeConfig.PDF_A })
|
||||||
component.discardChanges()
|
component.discardChanges()
|
||||||
expect(component.configForm.get('output_type').value).toEqual(
|
expect(component.configForm.get('output_type').value).toEqual(
|
||||||
OutputTypeConfig.PDF_A2
|
OutputTypeConfig.PDF_A2
|
||||||
@ -95,9 +95,9 @@ describe('ConfigComponent', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should support JSON validation for e.g. user_args', () => {
|
it('should support JSON validation for e.g. user_args', () => {
|
||||||
component.configForm.get('user_args').patchValue('{ foo bar }')
|
component.configForm.patchValue({ user_args: '{ foo bar }' })
|
||||||
expect(component.errors).toEqual({ user_args: 'Invalid JSON' })
|
expect(component.errors).toEqual({ user_args: 'Invalid JSON' })
|
||||||
component.configForm.get('user_args').patchValue('{ "foo": "bar" }')
|
component.configForm.patchValue({ user_args: '{ "foo": "bar" }' })
|
||||||
expect(component.errors).toEqual({ user_args: null })
|
expect(component.errors).toEqual({ user_args: null })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -31,22 +31,8 @@ export class ConfigComponent
|
|||||||
{
|
{
|
||||||
public readonly ConfigOptionType = ConfigOptionType
|
public readonly ConfigOptionType = ConfigOptionType
|
||||||
|
|
||||||
public configForm = new FormGroup({
|
// generated dynamically
|
||||||
id: new FormControl(),
|
public configForm = new FormGroup({})
|
||||||
output_type: new FormControl(),
|
|
||||||
pages: new FormControl(),
|
|
||||||
language: new FormControl(),
|
|
||||||
mode: new FormControl(),
|
|
||||||
skip_archive_file: new FormControl(),
|
|
||||||
image_dpi: new FormControl(),
|
|
||||||
unpaper_clean: new FormControl(),
|
|
||||||
deskew: new FormControl(),
|
|
||||||
rotate_pages: new FormControl(),
|
|
||||||
rotate_pages_threshold: new FormControl(),
|
|
||||||
max_image_pixels: new FormControl(),
|
|
||||||
color_conversion_strategy: new FormControl(),
|
|
||||||
user_args: new FormControl(),
|
|
||||||
})
|
|
||||||
|
|
||||||
public errors = {}
|
public errors = {}
|
||||||
|
|
||||||
@ -72,6 +58,10 @@ export class ConfigComponent
|
|||||||
private toastService: ToastService
|
private toastService: ToastService
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
|
this.configForm.addControl('id', new FormControl())
|
||||||
|
PaperlessConfigOptions.forEach((option) => {
|
||||||
|
this.configForm.addControl(option.key, new FormControl())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@ -90,11 +80,15 @@ export class ConfigComponent
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// validate JSON input for user_args
|
// validate JSON inputs
|
||||||
|
PaperlessConfigOptions.filter(
|
||||||
|
(o) => o.type === ConfigOptionType.JSON
|
||||||
|
).forEach((option) => {
|
||||||
this.configForm
|
this.configForm
|
||||||
.get('user_args')
|
.get(option.key)
|
||||||
.addValidators((control: AbstractControl) => {
|
.addValidators((control: AbstractControl) => {
|
||||||
if (!control.value || control.value.toString().length === 0) return null
|
if (!control.value || control.value.toString().length === 0)
|
||||||
|
return null
|
||||||
try {
|
try {
|
||||||
JSON.parse(control.value)
|
JSON.parse(control.value)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -106,11 +100,12 @@ export class ConfigComponent
|
|||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
this.configForm.get('user_args').statusChanges.subscribe((status) => {
|
this.configForm.get(option.key).statusChanges.subscribe((status) => {
|
||||||
this.errors['user_args'] =
|
this.errors[option.key] =
|
||||||
status === 'INVALID' ? $localize`Invalid JSON` : null
|
status === 'INVALID' ? $localize`Invalid JSON` : null
|
||||||
})
|
})
|
||||||
this.configForm.get('user_args').updateValueAndValidity()
|
this.configForm.get(option.key).updateValueAndValidity()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
@ -131,7 +126,6 @@ export class ConfigComponent
|
|||||||
|
|
||||||
this.isDirty$ = dirtyCheck(this.configForm, this.store.asObservable())
|
this.isDirty$ = dirtyCheck(this.configForm, this.store.asObservable())
|
||||||
}
|
}
|
||||||
|
|
||||||
this.configForm.patchValue(config)
|
this.configForm.patchValue(config)
|
||||||
|
|
||||||
this.initialConfig = config
|
this.initialConfig = config
|
||||||
|
@ -42,6 +42,7 @@ export enum ConfigOptionType {
|
|||||||
Number = 'number',
|
Number = 'number',
|
||||||
Select = 'select',
|
Select = 'select',
|
||||||
Boolean = 'boolean',
|
Boolean = 'boolean',
|
||||||
|
JSON = 'json',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ConfigCategory = {
|
export const ConfigCategory = {
|
||||||
@ -52,12 +53,12 @@ export interface ConfigOption {
|
|||||||
key: string
|
key: string
|
||||||
title: string
|
title: string
|
||||||
type: ConfigOptionType
|
type: ConfigOptionType
|
||||||
choices?: Array<string>
|
choices?: Array<{ id: string; name: string }>
|
||||||
config_key?: string
|
config_key?: string
|
||||||
category: string
|
category: string
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapToFlatChoices(enumObj: Object): Array<any> {
|
function mapToItems(enumObj: Object): Array<{ id: string; name: string }> {
|
||||||
return Object.keys(enumObj).map((key) => {
|
return Object.keys(enumObj).map((key) => {
|
||||||
return {
|
return {
|
||||||
id: enumObj[key],
|
id: enumObj[key],
|
||||||
@ -71,10 +72,17 @@ export const PaperlessConfigOptions: ConfigOption[] = [
|
|||||||
key: 'output_type',
|
key: 'output_type',
|
||||||
title: $localize`Output Type`,
|
title: $localize`Output Type`,
|
||||||
type: ConfigOptionType.Select,
|
type: ConfigOptionType.Select,
|
||||||
choices: mapToFlatChoices(OutputTypeConfig),
|
choices: mapToItems(OutputTypeConfig),
|
||||||
config_key: 'PAPERLESS_OCR_OUTPUT_TYPE',
|
config_key: 'PAPERLESS_OCR_OUTPUT_TYPE',
|
||||||
category: ConfigCategory.OCR,
|
category: ConfigCategory.OCR,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'language',
|
||||||
|
title: $localize`Language`,
|
||||||
|
type: ConfigOptionType.String,
|
||||||
|
config_key: 'PAPERLESS_OCR_LANGUAGE',
|
||||||
|
category: ConfigCategory.OCR,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'pages',
|
key: 'pages',
|
||||||
title: $localize`Pages`,
|
title: $localize`Pages`,
|
||||||
@ -86,7 +94,7 @@ export const PaperlessConfigOptions: ConfigOption[] = [
|
|||||||
key: 'mode',
|
key: 'mode',
|
||||||
title: $localize`Mode`,
|
title: $localize`Mode`,
|
||||||
type: ConfigOptionType.Select,
|
type: ConfigOptionType.Select,
|
||||||
choices: mapToFlatChoices(ModeConfig),
|
choices: mapToItems(ModeConfig),
|
||||||
config_key: 'PAPERLESS_OCR_MODE',
|
config_key: 'PAPERLESS_OCR_MODE',
|
||||||
category: ConfigCategory.OCR,
|
category: ConfigCategory.OCR,
|
||||||
},
|
},
|
||||||
@ -94,7 +102,7 @@ export const PaperlessConfigOptions: ConfigOption[] = [
|
|||||||
key: 'skip_archive_file',
|
key: 'skip_archive_file',
|
||||||
title: $localize`Skip Archive File`,
|
title: $localize`Skip Archive File`,
|
||||||
type: ConfigOptionType.Select,
|
type: ConfigOptionType.Select,
|
||||||
choices: mapToFlatChoices(ArchiveFileConfig),
|
choices: mapToItems(ArchiveFileConfig),
|
||||||
config_key: 'PAPERLESS_OCR_SKIP_ARCHIVE_FILE',
|
config_key: 'PAPERLESS_OCR_SKIP_ARCHIVE_FILE',
|
||||||
category: ConfigCategory.OCR,
|
category: ConfigCategory.OCR,
|
||||||
},
|
},
|
||||||
@ -109,7 +117,7 @@ export const PaperlessConfigOptions: ConfigOption[] = [
|
|||||||
key: 'unpaper_clean',
|
key: 'unpaper_clean',
|
||||||
title: $localize`Clean`,
|
title: $localize`Clean`,
|
||||||
type: ConfigOptionType.Select,
|
type: ConfigOptionType.Select,
|
||||||
choices: mapToFlatChoices(CleanConfig),
|
choices: mapToItems(CleanConfig),
|
||||||
config_key: 'PAPERLESS_OCR_CLEAN',
|
config_key: 'PAPERLESS_OCR_CLEAN',
|
||||||
category: ConfigCategory.OCR,
|
category: ConfigCategory.OCR,
|
||||||
},
|
},
|
||||||
@ -145,14 +153,14 @@ export const PaperlessConfigOptions: ConfigOption[] = [
|
|||||||
key: 'color_conversion_strategy',
|
key: 'color_conversion_strategy',
|
||||||
title: $localize`Color Conversion Strategy`,
|
title: $localize`Color Conversion Strategy`,
|
||||||
type: ConfigOptionType.Select,
|
type: ConfigOptionType.Select,
|
||||||
choices: mapToFlatChoices(ColorConvertConfig),
|
choices: mapToItems(ColorConvertConfig),
|
||||||
config_key: 'PAPERLESS_OCR_COLOR_CONVERSION_STRATEGY',
|
config_key: 'PAPERLESS_OCR_COLOR_CONVERSION_STRATEGY',
|
||||||
category: ConfigCategory.OCR,
|
category: ConfigCategory.OCR,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'user_args',
|
key: 'user_args',
|
||||||
title: $localize`OCR Arguments`,
|
title: $localize`OCR Arguments`,
|
||||||
type: ConfigOptionType.String,
|
type: ConfigOptionType.JSON,
|
||||||
config_key: 'PAPERLESS_OCR_USER_ARGS',
|
config_key: 'PAPERLESS_OCR_USER_ARGS',
|
||||||
category: ConfigCategory.OCR,
|
category: ConfigCategory.OCR,
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user