|
@@ -8,25 +8,27 @@ import { TemplateRef } from '@angular/core';
|
|
|
import { ValidatorFn, AsyncValidatorFn } from '@angular/forms';
|
|
|
import { ValueTransformer } from './../interfaces';
|
|
|
import { standardModifiers, standardTransformer } from './../utils';
|
|
|
+import { BehaviorSubject } from 'rxjs';
|
|
|
|
|
|
interface ISimpleFieldMetaData {
|
|
|
- name: string;
|
|
|
- type?: string;
|
|
|
- label?: string;
|
|
|
- value?: any;
|
|
|
- checkedValue?: boolean|number|string;
|
|
|
- default?: any;
|
|
|
- placeholder?: string;
|
|
|
- class?: string | string[];
|
|
|
- id?: string;
|
|
|
- disabled?: boolean;
|
|
|
- change?: string;
|
|
|
- source?: string;
|
|
|
- before?: string;
|
|
|
- after?: string;
|
|
|
- validators?: ValidatorFn[];
|
|
|
- asyncValidators?: AsyncValidatorFn[];
|
|
|
- valFailureMsgs?: StringMap<any>;
|
|
|
+ name: string;
|
|
|
+ type?: string;
|
|
|
+ label?: string;
|
|
|
+ value?: any;
|
|
|
+ checkedValue?: boolean | number | string;
|
|
|
+ default?: any;
|
|
|
+ placeholder?: string;
|
|
|
+ class?: string | string[];
|
|
|
+ id?: string;
|
|
|
+ disabled?: boolean;
|
|
|
+ change?: string;
|
|
|
+ transform?: ValueTransformer
|
|
|
+ source?: string;
|
|
|
+ before?: string;
|
|
|
+ after?: string;
|
|
|
+ validators?: ValidatorFn[];
|
|
|
+ asyncValidators?: AsyncValidatorFn[];
|
|
|
+ valFailureMsgs?: StringMap<any>;
|
|
|
}
|
|
|
|
|
|
interface IOption {
|
|
@@ -35,8 +37,8 @@ interface IOption {
|
|
|
}
|
|
|
|
|
|
interface IOptionsFieldMetaData extends ISimpleFieldMetaData {
|
|
|
- options: string[] | IOption[] | (() => IOption[]);
|
|
|
- horizontal?: boolean;
|
|
|
+ options: string[] | IOption[] | (() => IOption[] | BehaviorSubject<IOptionsFieldMetaData['options']>);
|
|
|
+ horizontal?: boolean;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -82,6 +84,7 @@ abstract class SimpleField {
|
|
|
id?: string;
|
|
|
disabled = false;
|
|
|
change?: string;
|
|
|
+ transform?: ValueTransformer;
|
|
|
validators: ValidatorFn|ValidatorFn[] = [];
|
|
|
asyncValidators: AsyncValidatorFn|AsyncValidatorFn[] = [];
|
|
|
valFailureMsgs: StringMap<any> = {};
|
|
@@ -142,15 +145,28 @@ class Option implements IOption {
|
|
|
}
|
|
|
|
|
|
abstract class OptionsField extends SimpleField {
|
|
|
+
|
|
|
options: Option[] | (() => Option[]) = [];
|
|
|
- constructor(meta: IOptionsFieldMetaData, context?: any) {
|
|
|
+
|
|
|
+ constructor(meta: IOptionsFieldMetaData, private context?: any) {
|
|
|
super(meta);
|
|
|
+ if (meta.options instanceof BehaviorSubject) {
|
|
|
+ meta.options.subscribe(opts => this.constructOptions(opts));
|
|
|
+ } else {
|
|
|
+ this.constructOptions(meta.options);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private constructOptions(optProvider: IOptionsFieldMetaData['options']) {
|
|
|
let options;
|
|
|
- if (typeof meta.options === 'function') {
|
|
|
- const boundFn = meta.options.bind(context);
|
|
|
+ if (typeof optProvider === 'function') {
|
|
|
+ const boundFn = optProvider.bind(this.context);
|
|
|
options = boundFn();
|
|
|
+ if (options instanceof BehaviorSubject) {
|
|
|
+ options.subscribe(opts => this.constructOptions(opts));
|
|
|
+ }
|
|
|
} else {
|
|
|
- options = meta.options;
|
|
|
+ options = optProvider;
|
|
|
}
|
|
|
if (Array.isArray(options)) {
|
|
|
this.options = options.reduce((acc, opt) => { acc.push(new Option(opt)); return acc; }, []);
|
|
@@ -161,6 +177,7 @@ abstract class OptionsField extends SimpleField {
|
|
|
];
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
|
|
@@ -201,6 +218,7 @@ class CheckboxField extends SimpleField {
|
|
|
default: any = false;
|
|
|
checkedValue: boolean|number|string = true;
|
|
|
rowLabel: null;
|
|
|
+ editable: boolean;
|
|
|
constructor(meta: ISimpleFieldMetaData) {
|
|
|
super(meta);
|
|
|
if (meta.default) {
|
|
@@ -215,9 +233,6 @@ class CheckboxField extends SimpleField {
|
|
|
if (typeof meta.value === 'undefined') {
|
|
|
this.value = this.default;
|
|
|
}
|
|
|
- if (!meta.label) {
|
|
|
- this.label = unCamelCase(this.checkedValue.toString());
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -256,8 +271,10 @@ class CheckboxGroup {
|
|
|
label?: string;
|
|
|
groupName: string;
|
|
|
firstEnablesRest?: boolean;
|
|
|
+ editable: boolean = false;
|
|
|
showAllOrNone?: boolean;
|
|
|
meta: CheckboxField[] | { [key: string]: CheckboxField };
|
|
|
+ transformer?: ValueTransformer;
|
|
|
constructor(groupmeta: any) {
|
|
|
Object.assign(this, groupmeta);
|
|
|
if (typeof this.label === 'undefined') {
|
|
@@ -266,13 +283,14 @@ class CheckboxGroup {
|
|
|
this.label = unCamelCase(this.name);
|
|
|
}
|
|
|
|
|
|
+ const passThrough = { editable: this.editable, transformer: this.transformer };
|
|
|
if (Array.isArray(groupmeta.meta)) {
|
|
|
const arrayMembers = groupmeta.meta;
|
|
|
- this.meta = arrayMembers.map(cb => new CheckboxField(cb));
|
|
|
+ this.meta = arrayMembers.map(cb => new CheckboxField({ ...cb, ...passThrough }));
|
|
|
} else {
|
|
|
const groupMembers = groupmeta.meta;
|
|
|
this.meta = Object.entries(groupMembers)
|
|
|
- .map( ([key, cb]) => [key, new CheckboxField(cb as ISimpleFieldMetaData)] )
|
|
|
+ .map( ([key, cb]: [string, ISimpleFieldMetaData]) => [key, new CheckboxField({ label: unCamelCase(cb.checkedValue || cb.value).toString(), ...cb, ...passThrough })] )
|
|
|
.reduce((res, [key, cbf]) => { res[key as string] = cbf; return res; }, {});
|
|
|
}
|
|
|
}
|
|
@@ -291,7 +309,7 @@ class DatetimeField extends SimpleField {
|
|
|
value: Date | string;
|
|
|
constructor(meta) {
|
|
|
super(meta);
|
|
|
- if (typeof this.value === 'string') {
|
|
|
+ if (typeof this.value === 'string' && this.value) {
|
|
|
this.value = new Date(this.value);
|
|
|
}
|
|
|
if (!(this.value instanceof Date)) {
|