|
@@ -19,14 +19,14 @@
|
|
|
|
|
|
import { FormBuilder, FormGroup, FormControl, ValidatorFn, AsyncValidatorFn } from '@angular/forms';
|
|
|
import { reduce } from 'lodash/fp';
|
|
|
-import * as fmdModels from './../models';
|
|
|
+import * as fmdModels from '../models/field.model';
|
|
|
|
|
|
// REMINDER: Import this directly from @angular/forms when we upgrade to Angular 6
|
|
|
// While we're still on Angular 5 just declare it
|
|
|
interface AbstractControlOptions {
|
|
|
- validators?: ValidatorFn | ValidatorFn[] | null
|
|
|
- asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null
|
|
|
- updateOn?: 'change' | 'blur' | 'submit'
|
|
|
+ validators?: ValidatorFn | ValidatorFn[] | null;
|
|
|
+ asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null;
|
|
|
+ updateOn?: 'change' | 'blur' | 'submit';
|
|
|
}
|
|
|
|
|
|
|
|
@@ -52,20 +52,20 @@ const autoMeta = model => Object.entries(model)
|
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
const combineMetaForField = (metaF, extraMetaF) => Object.assign(metaF, extraMetaF);
|
|
|
-const combineExtraMeta = (metaG, extraMeta) => {
|
|
|
+const combineExtraMeta = (metaG, extraMeta, createFromExtra = false) => {
|
|
|
const combinedMeta = {};
|
|
|
Object.entries(extraMeta).forEach(([key, val]) => {
|
|
|
- if (typeof metaG[key] === 'object') {
|
|
|
- combinedMeta[key] = (<any>val).meta ?
|
|
|
- combineMetaForField(metaG[key], { meta: combineExtraMeta(metaG[key].meta, (<any>val).meta) }) :
|
|
|
- combineMetaForField(metaG[key], val);
|
|
|
+ if (typeof metaG[key] === 'object' || createFromExtra) {
|
|
|
+ combinedMeta[key] = metaG[key] && (<any>val).meta ?
|
|
|
+ combineMetaForField(metaG[key], { meta: combineExtraMeta(metaG[key].meta, (<any>val).meta, createFromExtra) }) :
|
|
|
+ combineMetaForField(metaG[key] || {}, val);
|
|
|
}
|
|
|
});
|
|
|
return { ...metaG, ...combinedMeta };
|
|
|
};
|
|
|
|
|
|
// Combine model with overrides (after automatically generating metadata from the model)
|
|
|
-const combineModelWithMeta = (model, extraMeta) => combineExtraMeta(autoMeta(model), extraMeta);
|
|
|
+const combineModelWithMeta = (model, extraMeta, createFromExtra = false) => combineExtraMeta(autoMeta(model), extraMeta, createFromExtra);
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
@@ -74,7 +74,6 @@ const combineModelWithMeta = (model, extraMeta) => combineExtraMeta(autoMeta(mod
|
|
|
|
|
|
const buildFieldClassName = (t = 'text') => {
|
|
|
const start = t[0].toUpperCase() + t.slice(1);
|
|
|
- console.log(start);
|
|
|
if (start === 'Container' || t.slice(-5) === 'Group') {
|
|
|
return start;
|
|
|
}
|
|
@@ -94,15 +93,15 @@ const buildModeledField = metaFoG => {
|
|
|
const buildModeledFieldGroupMember = metaFoG => {
|
|
|
const modeledGroupMember = buildModeledField(metaFoG);
|
|
|
if (isContainer(metaFoG)) {
|
|
|
- modeledGroupMember.meta = _buildModeledFieldGroup(metaFoG.meta);
|
|
|
+ modeledGroupMember.meta = _buildFieldSpecificMeta(metaFoG.meta);
|
|
|
}
|
|
|
return modeledGroupMember;
|
|
|
};
|
|
|
|
|
|
// Build Form Group
|
|
|
const buildModeledFieldGroupReducerIteree = (res, metaFoG) => Object.assign(res, { [metaFoG.name]: buildModeledFieldGroupMember(metaFoG) });
|
|
|
-const _buildModeledFieldGroup = metaG => reduce(buildModeledFieldGroupReducerIteree, {}, metaG);
|
|
|
-const buildFieldSpecificMeta = metaG => _buildModeledFieldGroup(metaG);
|
|
|
+const _buildFieldSpecificMeta = metaG => reduce(buildModeledFieldGroupReducerIteree, {}, metaG);
|
|
|
+const buildFieldSpecificMeta = metaG => _buildFieldSpecificMeta(addMissingNames(metaG));
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
@@ -131,8 +130,13 @@ const buildFormGroupFunctionFactory = (fb: FormBuilder): (meta) => FormGroup =>
|
|
|
const _buildFormGroup = _metaG => fb.group(reduce(buildFormGroupReducerIteree, {}, _metaG));
|
|
|
|
|
|
const buildFormGroup = metaG => {
|
|
|
- const metaWithNames = addMissingNames(metaG);
|
|
|
- return _buildFormGroup(metaWithNames);
|
|
|
+ // Ensure that we have Field-Specific Metadata, not raw Objects
|
|
|
+ const metaWithNameKeys = addMissingNames(metaG);
|
|
|
+ console.log(metaWithNameKeys);
|
|
|
+ // MAYBE only run this if first entry isn't right, for reasons of efficiency
|
|
|
+ const fieldModeledMeta = addMissingFieldSpecificMeta(metaWithNameKeys);
|
|
|
+ console.log(fieldModeledMeta);
|
|
|
+ return _buildFormGroup(fieldModeledMeta);
|
|
|
};
|
|
|
return buildFormGroup;
|
|
|
};
|
|
@@ -151,7 +155,7 @@ const isGroup = (metaFoG): boolean => !!metaFoG.meta;
|
|
|
|
|
|
// Is Container
|
|
|
// Helper function to distinguish container group (a group of child fields)
|
|
|
-const isContainer = (metaFoG): boolean => isGroup(metaFoG) && (metaFoG.type === 'container' || typeof metaFoG.type === 'undefined');
|
|
|
+const isContainer = (metaFoG): boolean => isGroup(metaFoG) && (!metaFoG.type || metaFoG.type.toLowerCase() === 'container');
|
|
|
|
|
|
// Add Missing Names
|
|
|
// Helper function to add any missing 'name' properties to Fields and Groups using property's key, recursively
|
|
@@ -159,7 +163,7 @@ const addNameIfMissing = (metaFoG, key) => metaFoG.name ? metaFoG : addProp(meta
|
|
|
const addNameToSelfAndChildren = ( [key, metaFoG] ) => {
|
|
|
metaFoG = addNameIfMissing(metaFoG, key);
|
|
|
if (isGroup(metaFoG)) {
|
|
|
- metaFoG.meta = addMissingNames(metaFoG.meta); // Recursion
|
|
|
+ metaFoG.meta = Array.isArray(metaFoG.meta) ? Object.values(addMissingNames(metaFoG.meta)) : addMissingNames(metaFoG.meta); // Recursion
|
|
|
}
|
|
|
return [key, metaFoG];
|
|
|
};
|
|
@@ -168,6 +172,19 @@ const addMissingNames = metaG => Object.entries(metaG)
|
|
|
.reduce((res, [key, val]) => addProp(res, key, val), {});
|
|
|
|
|
|
|
|
|
+// Add Missing Field-Specific Meta
|
|
|
+// Helper function to add any missing Field-Specific Metadata (using models in dynaform/models), recursively
|
|
|
+// Checks the constrctor, which should NOT be a plain Object, but rather TextField, TextareaField, SelectField, etc.
|
|
|
+const add_FSM_IfMissing = metaFoG => metaFoG.constructor.name === 'Object' ? buildModeledFieldGroupMember(metaFoG) : metaFoG;
|
|
|
+const add_FSM_ToSelfAndChildren = ( [key, metaFoG] ) => {
|
|
|
+ metaFoG = add_FSM_IfMissing(metaFoG);
|
|
|
+ return [key, metaFoG];
|
|
|
+};
|
|
|
+const addMissingFieldSpecificMeta = metaG => Object.entries(metaG)
|
|
|
+ .map(add_FSM_ToSelfAndChildren)
|
|
|
+ .reduce((res, [key, val]) => addProp(res, key, val), {});
|
|
|
+
|
|
|
+
|
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
|
// Exports
|
|
|
// ---------------------------------------------------------------------------------------------------------------------
|