// Utility functions for Dyynaform consumers import { FormControl, FormGroup, ValidationErrors } from '@angular/forms'; import { ValueTransformer } from './interfaces'; import { Observable, of, merge } from 'rxjs'; import { filter, map, mapTo, switchMap, } from 'rxjs/internal/operators'; // Dropdown Modified Input - Starts With / Contains / Matches const standardModifiers = ['Starts with', 'Contains', 'Matches']; const standardTransformer: ValueTransformer = { inputFn: val => { let modifier = 'Starts with'; if (/^%.*?%$/.test(val)) { modifier = 'Contains'; } else if (/^[^%].*?[^%]$/.test(val)) { modifier = 'Matches'; } else if (/^%.*/.test(val)) { modifier = 'Starts with'; } const transformedVal = val.replace(/%/g, '').trim(); return { modifier, value: transformedVal }; }, outputFn: (mod, val) => { let transformedValue; switch (mod) { case 'Starts with': transformedValue = `${val}%`; break; case 'Contains': transformedValue = `%${val}%`; break; case 'Matches': default: transformedValue = val; break; } return transformedValue; } }; // Generate array from CSV string const toArrTag = (str: TemplateStringsArray): string[] => str[0].split(',').map(key => key.trim()); // Pad array const arrayPad = (length: number) => (arr: string[]): any[] => [...arr, ...Array(length - arr.length).fill('')]; // Utility function for casting an array to metadata (useful for components that render FormGroups) const arrayToMeta = array => array.map(val => ({ name: val, 'value' : val })); // Exclude 'fieldsToExclude' from obj, returning a new object // fieldsToExclude can be an array of field keys or a CSV of field keys const excludeFields = (obj: StringMap, fieldsToExclude: string | string[]) => { const ex = Array.isArray(fieldsToExclude) ? fieldsToExclude : fieldsToExclude.split(',').map(key => key.trim()); return Object.entries(obj).reduce( (res, [key, val]) => ex.includes(key) ? res : { ...res, [key]: val }, {} ); }; // Higher order function that takes a bound test function and failure flag // and returns an AsyncValidator-compatible function // that in turn returns an Observable of ValidationErrors const makeAsyncTest = (boundFnName: string, failureFlag: string): (fc: FormControl | FormGroup) => Observable => { let initialValue; return function(fc: FormControl | FormGroup | 'RESET'): Observable { if (fc === 'RESET') { // Special value that resets the initial value initialValue = ''; return of({}); } if (fc.pristine) { initialValue = fc.value; } return merge( of(fc).pipe( filter(_fc => _fc.value !== initialValue), switchMap(_fc => this[boundFnName](_fc.value, _fc.root)), map(res => res ? {} : { [failureFlag]: true } ) ), of(fc).pipe( filter(_fc => _fc.value === initialValue), mapTo({}) ) ); }; }; export { standardModifiers, standardTransformer, toArrTag, arrayPad, arrayToMeta, excludeFields, makeAsyncTest };