[SDC-29] catalog 1707 rebase commit.
[sdc.git] / catalog-ui / src / app / directives / property-types / data-type-fields-structure / data-type-fields-structure.ts
1 /**
2  * Created by obarda on 1/27/2016.
3  */
4 'use strict';
5 import {DataTypesService} from "app/services";
6 import { ValidationUtils } from "app/utils";
7 import { DataTypePropertyModel } from "app/models/data-type-properties";
8 import { DataTypesMap} from "app/models";
9
10 export interface IDataTypeFieldsStructureScope extends ng.IScope {
11     parentFormObj:ng.IFormController;
12     dataTypeProperties:Array<DataTypePropertyModel>;
13     typeName:string;
14     valueObjRef:any;
15     propertyNameValidationPattern:RegExp;
16     fieldsPrefixName:string;
17     readOnly:boolean;
18     currentTypeDefaultValue:any;
19     types:DataTypesMap;
20     expandByDefault:boolean;
21     expand:boolean;
22     expanded:boolean;
23     dataTypesService:DataTypesService;
24
25     expandAndCollapse():void;
26     getValidationPattern(type:string):RegExp;
27     validateIntRange(value:string):boolean;
28     onValueChange(propertyName:string, type:string):void
29     inputOnValueChange(property:any):void;
30 }
31
32
33 export class DataTypeFieldsStructureDirective implements ng.IDirective {
34
35     constructor(private DataTypesService:DataTypesService,
36                 private PropertyNameValidationPattern:RegExp,
37                 private ValidationUtils:ValidationUtils) {
38     }
39
40     scope = {
41         valueObjRef: '=',
42         typeName: '=',
43         parentFormObj: '=',
44         fieldsPrefixName: '=',
45         readOnly: '=',
46         defaultValue: '@',
47         //     types: '=',
48         expandByDefault: '='
49     };
50
51     restrict = 'E';
52     replace = true;
53     template = ():string => {
54         return require('./data-type-fields-structure.html');
55     };
56     //public types=Utils.Constants.PROPERTY_DATA.TYPES;
57
58     //get data type properties array and return object with the properties and their default value
59     //(for example: get: [{name:"prop1",defaultValue:1 ...},{name:"prop2", defaultValue:"bla bla" ...}]
60     //              return: {prop1: 1, prop2: "bla bla"}
61     private getDefaultValue = (dataTypeProperties:Array<DataTypePropertyModel>):any => {
62         let defaultValue = {};
63         for (let i = 0; i < dataTypeProperties.length; i++) {
64             if (dataTypeProperties[i].type != 'string') {
65                 if (!angular.isUndefined(dataTypeProperties[i].defaultValue)) {
66                     defaultValue[dataTypeProperties[i].name] = JSON.parse(dataTypeProperties[i].defaultValue);
67                 }
68             } else {
69                 defaultValue[dataTypeProperties[i].name] = dataTypeProperties[i].defaultValue;
70             }
71         }
72         return defaultValue;
73     };
74
75     private initDataOnScope = (scope:any, $attr:any):void => {
76         scope.dataTypesService = this.DataTypesService;
77         scope.dataTypeProperties = this.DataTypesService.getFirsLevelOfDataTypeProperties(scope.typeName);
78         if ($attr.defaultValue) {
79             scope.currentTypeDefaultValue = JSON.parse($attr.defaultValue);
80         } else {
81             scope.currentTypeDefaultValue = this.getDefaultValue(scope.dataTypeProperties);
82         }
83
84         if (!scope.valueObjRef) {
85             scope.valueObjRef = {};
86         }
87
88         _.forEach(scope.currentTypeDefaultValue, (value, key)=> {
89             if (angular.isUndefined(scope.valueObjRef[key])) {
90                 if (typeof scope.currentTypeDefaultValue[key] == 'object') {
91                     angular.copy(scope.currentTypeDefaultValue[key], scope.valueObjRef[key]);
92                 } else {
93                     scope.valueObjRef[key] = scope.currentTypeDefaultValue[key];
94                 }
95             }
96         });
97     };
98
99     private rerender = (scope:any):void => {
100         scope.expanded = false;
101         scope.expand = false;
102         if (scope.expandByDefault) {
103             scope.expandAndCollapse();
104         }
105     };
106
107     link = (scope:IDataTypeFieldsStructureScope, element:any, $attr:any) => {
108         scope.propertyNameValidationPattern = this.PropertyNameValidationPattern;
109
110         scope.$watchCollection('[typeName,fieldsPrefixName]', (newData:any):void => {
111             this.rerender(scope);
112         });
113
114
115         scope.expandAndCollapse = ():void => {
116             if (!scope.expanded) {
117                 this.initDataOnScope(scope, $attr);
118                 scope.expanded = true;
119             }
120             scope.expand = !scope.expand;
121         };
122
123         scope.getValidationPattern = (type:string):RegExp => {
124             return this.ValidationUtils.getValidationPattern(type);
125         };
126
127         scope.validateIntRange = (value:string):boolean => {
128             return !value || this.ValidationUtils.validateIntRange(value);
129         };
130
131         scope.onValueChange = (propertyName:string, type:string):void => {
132             scope.valueObjRef[propertyName] = !angular.isUndefined(scope.valueObjRef[propertyName]) ? scope.valueObjRef[propertyName] : scope.currentTypeDefaultValue[propertyName];
133             if (scope.valueObjRef[propertyName] && type != 'string') {
134                 scope.valueObjRef[propertyName] = JSON.parse(scope.valueObjRef[propertyName]);
135             }
136         };
137
138         scope.inputOnValueChange = (property:any) => {
139
140             let value = !scope.parentFormObj[scope.fieldsPrefixName + property.name].$error.pattern
141                 && ('integer' == property.type && scope.parentFormObj[scope.fieldsPrefixName + property.name].$setValidity('pattern', scope.validateIntRange(scope.valueObjRef[property.name]))
142                 || scope.onValueChange(property.name, (property.simpleType || property.type)));
143             return value;
144         }
145     };
146
147     public static factory = (DataTypesService:DataTypesService,
148                              PropertyNameValidationPattern:RegExp,
149                              ValidationUtils:ValidationUtils)=> {
150         return new DataTypeFieldsStructureDirective(DataTypesService, PropertyNameValidationPattern, ValidationUtils);
151     };
152 }
153
154 DataTypeFieldsStructureDirective.factory.$inject = ['Sdc.Services.DataTypesService', 'PropertyNameValidationPattern', 'ValidationUtils'];