|
|
|
@ -1,11 +1,12 @@ |
|
|
|
import {EXTENSIONS_FORM_PROP_DATA, EXTENSIONS_FORM_PROP} from './../../tokens/extensions.token'; |
|
|
|
import {ABP, AbpValidators, ConfigStateService, TrackByService} from '@abp/ng.core'; |
|
|
|
import { EXTENSIONS_FORM_PROP_DATA, EXTENSIONS_FORM_PROP } from './../../tokens/extensions.token'; |
|
|
|
import { ABP, AbpValidators, ConfigStateService, TrackByService } from '@abp/ng.core'; |
|
|
|
import { |
|
|
|
AfterViewInit, |
|
|
|
ChangeDetectionStrategy, |
|
|
|
ChangeDetectorRef, |
|
|
|
Component, |
|
|
|
ElementRef, Injector, |
|
|
|
ElementRef, |
|
|
|
Injector, |
|
|
|
Input, |
|
|
|
OnChanges, |
|
|
|
Optional, |
|
|
|
@ -20,17 +21,17 @@ import { |
|
|
|
ValidatorFn, |
|
|
|
Validators, |
|
|
|
} from '@angular/forms'; |
|
|
|
import {NgbDateAdapter, NgbTimeAdapter} from '@ng-bootstrap/ng-bootstrap'; |
|
|
|
import {Observable, of} from 'rxjs'; |
|
|
|
import {debounceTime, distinctUntilChanged, switchMap} from 'rxjs/operators'; |
|
|
|
import {DateAdapter} from '../../adapters/date.adapter'; |
|
|
|
import {TimeAdapter} from '../../adapters/time.adapter'; |
|
|
|
import {EXTRA_PROPERTIES_KEY} from '../../constants/extra-properties'; |
|
|
|
import {ePropType} from '../../enums/props.enum'; |
|
|
|
import {FormProp} from '../../models/form-props'; |
|
|
|
import {PropData} from '../../models/props'; |
|
|
|
import {selfFactory} from '../../utils/factory.util'; |
|
|
|
import {addTypeaheadTextSuffix} from '../../utils/typeahead.util'; |
|
|
|
import { NgbDateAdapter, NgbTimeAdapter } from '@ng-bootstrap/ng-bootstrap'; |
|
|
|
import { Observable, of } from 'rxjs'; |
|
|
|
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators'; |
|
|
|
import { DateAdapter } from '../../adapters/date.adapter'; |
|
|
|
import { TimeAdapter } from '../../adapters/time.adapter'; |
|
|
|
import { EXTRA_PROPERTIES_KEY } from '../../constants/extra-properties'; |
|
|
|
import { ePropType } from '../../enums/props.enum'; |
|
|
|
import { FormProp } from '../../models/form-props'; |
|
|
|
import { PropData } from '../../models/props'; |
|
|
|
import { selfFactory } from '../../utils/factory.util'; |
|
|
|
import { addTypeaheadTextSuffix } from '../../utils/typeahead.util'; |
|
|
|
|
|
|
|
@Component({ |
|
|
|
selector: 'abp-extensible-form-prop', |
|
|
|
@ -42,8 +43,8 @@ import {addTypeaheadTextSuffix} from '../../utils/typeahead.util'; |
|
|
|
useFactory: selfFactory, |
|
|
|
deps: [[new Optional(), new SkipSelf(), ControlContainer]], |
|
|
|
}, |
|
|
|
{provide: NgbDateAdapter, useClass: DateAdapter}, |
|
|
|
{provide: NgbTimeAdapter, useClass: TimeAdapter}, |
|
|
|
{ provide: NgbDateAdapter, useClass: DateAdapter }, |
|
|
|
{ provide: NgbTimeAdapter, useClass: TimeAdapter }, |
|
|
|
], |
|
|
|
}) |
|
|
|
export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit { |
|
|
|
@ -55,7 +56,7 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit { |
|
|
|
|
|
|
|
@ViewChild('field') private fieldRef!: ElementRef<HTMLElement>; |
|
|
|
|
|
|
|
public injectorForCustomComponent: Injector |
|
|
|
public injectorForCustomComponent: Injector; |
|
|
|
|
|
|
|
asterisk = ''; |
|
|
|
|
|
|
|
@ -72,13 +73,12 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit { |
|
|
|
disabledFn = (data: PropData) => false; |
|
|
|
|
|
|
|
get disabled() { |
|
|
|
return this.disabledFn(this.data) |
|
|
|
return this.disabledFn(this.data); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
setTypeaheadValue(selectedOption: ABP.Option<string>) { |
|
|
|
this.typeaheadModel = selectedOption || {key: null, value: null}; |
|
|
|
const {key, value} = this.typeaheadModel; |
|
|
|
this.typeaheadModel = selectedOption || { key: null, value: null }; |
|
|
|
const { key, value } = this.typeaheadModel; |
|
|
|
const [keyControl, valueControl] = this.getTypeaheadControls(); |
|
|
|
if (valueControl?.value && !value) valueControl.markAsDirty(); |
|
|
|
keyControl?.setValue(key); |
|
|
|
@ -88,10 +88,10 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit { |
|
|
|
search = (text$: Observable<string>) => |
|
|
|
text$ |
|
|
|
? text$.pipe( |
|
|
|
debounceTime(300), |
|
|
|
distinctUntilChanged(), |
|
|
|
switchMap(text => this.prop.options(this.data, text)), |
|
|
|
) |
|
|
|
debounceTime(300), |
|
|
|
distinctUntilChanged(), |
|
|
|
switchMap(text => this.prop.options(this.data, text)), |
|
|
|
) |
|
|
|
: of([]); |
|
|
|
|
|
|
|
typeaheadFormatter = (option: ABP.Option<any>) => option.key; |
|
|
|
@ -112,13 +112,13 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit { |
|
|
|
public readonly track: TrackByService, |
|
|
|
protected configState: ConfigStateService, |
|
|
|
groupDirective: FormGroupDirective, |
|
|
|
private injector: Injector |
|
|
|
private injector: Injector, |
|
|
|
) { |
|
|
|
this.form = groupDirective.form; |
|
|
|
} |
|
|
|
|
|
|
|
private getTypeaheadControls() { |
|
|
|
const {name} = this.prop; |
|
|
|
const { name } = this.prop; |
|
|
|
const extraPropName = `${EXTRA_PROPERTIES_KEY}.${name}`; |
|
|
|
const keyControl = |
|
|
|
this.form.get(addTypeaheadTextSuffix(extraPropName)) || |
|
|
|
@ -139,7 +139,7 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit { |
|
|
|
|
|
|
|
getComponent(prop: FormProp): string { |
|
|
|
if (prop.template) { |
|
|
|
return 'template' |
|
|
|
return 'template'; |
|
|
|
} |
|
|
|
switch (prop.type) { |
|
|
|
case ePropType.Boolean: |
|
|
|
@ -181,21 +181,21 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
ngOnChanges({prop, data}: SimpleChanges) { |
|
|
|
ngOnChanges({ prop, data }: SimpleChanges) { |
|
|
|
const currentProp = prop?.currentValue as FormProp; |
|
|
|
const {options, readonly, disabled, validators, template} = currentProp || {}; |
|
|
|
const { options, readonly, disabled, validators, template } = currentProp || {}; |
|
|
|
if (template) { |
|
|
|
this.injectorForCustomComponent = Injector.create({ |
|
|
|
providers: [ |
|
|
|
{ |
|
|
|
provide: EXTENSIONS_FORM_PROP, |
|
|
|
useValue: currentProp |
|
|
|
useValue: currentProp, |
|
|
|
}, |
|
|
|
{ |
|
|
|
provide: EXTENSIONS_FORM_PROP_DATA, |
|
|
|
useValue: (data?.currentValue as PropData)?.record |
|
|
|
useValue: (data?.currentValue as PropData)?.record, |
|
|
|
}, |
|
|
|
{provide: ControlContainer, useExisting: FormGroupDirective} |
|
|
|
{ provide: ControlContainer, useExisting: FormGroupDirective }, |
|
|
|
], |
|
|
|
parent: this.injector, |
|
|
|
}); |
|
|
|
@ -214,10 +214,14 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit { |
|
|
|
|
|
|
|
const [keyControl, valueControl] = this.getTypeaheadControls(); |
|
|
|
if (keyControl && valueControl) |
|
|
|
this.typeaheadModel = {key: keyControl.value, value: valueControl.value}; |
|
|
|
this.typeaheadModel = { key: keyControl.value, value: valueControl.value }; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function isRequired(validator: ValidatorFn) { |
|
|
|
return validator === Validators.required || validator === AbpValidators.required || validator.name === 'required'; |
|
|
|
return ( |
|
|
|
validator === Validators.required || |
|
|
|
validator === AbpValidators.required || |
|
|
|
validator.name === 'required' |
|
|
|
); |
|
|
|
} |
|
|
|
|