aee4b3b6afa19930306a5b8b5ce57b45d603f5ee
[sdc.git] /
1 /**
2  * Created by obarda on 1/27/2016.
3  */
4 'use strict';
5 import {ValidationUtils} from "app/utils";
6 import { DataTypesService } from "app/services";
7 import { DataTypePropertyModel } from "app/models/data-type-properties";
8 import {DataTypesMap, PropertyModel} from "app/models";
9
10 export interface ISelectDataTypeFieldsStructureScope 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     path:string;
25     isParentAlreadyInput:boolean;
26
27     expandAndCollapse():void;
28     getValidationPattern(type:string):RegExp;
29     validateIntRange(value:string):boolean;
30     isAlreadyInput(property:PropertyModel):boolean;
31     setSelectedType(property:PropertyModel):void;
32     onValueChange(propertyName:string, type:string):void;
33 }
34
35
36 export class SelectDataTypeFieldsStructureDirective implements ng.IDirective {
37
38     constructor(private DataTypesService:DataTypesService,
39                 private PropertyNameValidationPattern:RegExp,
40                 private ValidationUtils:ValidationUtils) {
41     }
42
43     scope = {
44         valueObjRef: '=',
45         typeName: '=',
46         parentFormObj: '=',
47         fieldsPrefixName: '=',
48         readOnly: '=',
49         defaultValue: '@',
50         expandByDefault: '=',
51         path: '@',
52         isParentAlreadyInput: '='
53     };
54
55     restrict = 'E';
56     replace = true;
57     template = ():string => {
58         return require('./select-data-type-fields-structure.html');
59     };
60     // public types=Utils.Constants.PROPERTY_DATA.TYPES;
61
62     //get data type properties array and return object with the properties and their default value
63     //(for example: get: [{name:"prop1",defaultValue:1 ...},{name:"prop2", defaultValue:"bla bla" ...}]
64     //              return: {prop1: 1, prop2: "bla bla"}
65     private getDefaultValue = (dataTypeProperties:Array<DataTypePropertyModel>):any => {
66         let defaultValue = {};
67         for (let i = 0; i < dataTypeProperties.length; i++) {
68             if (dataTypeProperties[i].type != 'string') {
69                 if (!angular.isUndefined(dataTypeProperties[i].defaultValue)) {
70                     defaultValue[dataTypeProperties[i].name] = JSON.parse(dataTypeProperties[i].defaultValue);
71                 }
72             } else {
73                 defaultValue[dataTypeProperties[i].name] = dataTypeProperties[i].defaultValue;
74             }
75         }
76         return defaultValue;
77     };
78
79     private initDataOnScope = (scope:ISelectDataTypeFieldsStructureScope, $attr:any):void => {
80         scope.dataTypesService = this.DataTypesService;
81         scope.dataTypeProperties = angular.copy(this.DataTypesService.getFirsLevelOfDataTypeProperties(scope.typeName));
82         if ($attr.defaultValue) {
83             scope.currentTypeDefaultValue = JSON.parse($attr.defaultValue);
84         } else {
85             scope.currentTypeDefaultValue = this.getDefaultValue(scope.dataTypeProperties);
86         }
87
88         if (!scope.valueObjRef) {
89             scope.valueObjRef = {};
90         }
91
92         _.forEach(scope.currentTypeDefaultValue, (value, key)=> {
93             if (angular.isUndefined(scope.valueObjRef[key])) {
94                 if (typeof scope.currentTypeDefaultValue[key] == 'object') {
95                     angular.copy(scope.currentTypeDefaultValue[key], scope.valueObjRef[key]);
96                 } else {
97                     scope.valueObjRef[key] = scope.currentTypeDefaultValue[key];
98                 }
99             }
100         });
101     };
102
103     private rerender = (scope:any):void => {
104         scope.expanded = false;
105         scope.expand = false;
106         if (scope.expandByDefault) {
107             scope.expandAndCollapse();
108         }
109     };
110
111     link = (scope:ISelectDataTypeFieldsStructureScope, element:any, $attr:any) => {
112         scope.propertyNameValidationPattern = this.PropertyNameValidationPattern;
113
114         scope.$watchCollection('[typeName,fieldsPrefixName]', (newData:any):void => {
115             this.rerender(scope);
116         });
117
118
119         scope.expandAndCollapse = ():void => {
120             if (!scope.expanded) {
121                 this.initDataOnScope(scope, $attr);
122                 scope.expanded = true;
123             }
124             scope.expand = !scope.expand;
125         };
126
127         scope.getValidationPattern = (type:string):RegExp => {
128             return this.ValidationUtils.getValidationPattern(type);
129         };
130
131         scope.validateIntRange = (value:string):boolean => {
132             return !value || this.ValidationUtils.validateIntRange(value);
133         };
134
135         /*
136          check if property is alrady declered on the service by meatching the input name & the property name
137
138          */
139         scope.isAlreadyInput = (property:PropertyModel):boolean => {
140             if (scope.path) {
141                 if (scope.isParentAlreadyInput) {
142                     return true;
143                 }
144                 let parentInputName = this.DataTypesService.selectedInstance.normalizedName + '_' + scope.path.replace('#', '_');// set the input parent  as he need to declared as input
145                 let inputName = parentInputName + '_' + property.name;// set the input name as he need to declared as input
146                 let selectedProperty = _.find(this.DataTypesService.selectedComponentInputs, (componentInput)=> {
147                     if (componentInput.name == parentInputName) { //check if the parent(all the complex) is already declared
148                         scope.isParentAlreadyInput = true;
149                         return true;
150                     } else if (componentInput.name.substring(0, inputName.length) == inputName) { //check if specific property inside the complex
151                         return true;
152                     }
153                     //return componentInput.name == parentInputName || componentInput.name.substring(0,inputName.length) == inputName;//check if the parent(all the complex) is already declared or specific property inside the complex
154                 });
155                 if (selectedProperty) {
156                     return true;
157                 }
158             }
159             return false;
160         };
161
162         scope.setSelectedType = (property:PropertyModel):void=> {
163             scope.dataTypesService.selectedInput = property;
164             scope.dataTypesService.selectedPropertiesName = scope.path + '#' + property.name;
165         };
166
167         scope.onValueChange = (propertyName:string, type:string):void => {
168             scope.valueObjRef[propertyName] = !angular.isUndefined(scope.valueObjRef[propertyName]) ? scope.valueObjRef[propertyName] : scope.currentTypeDefaultValue[propertyName];
169             if (scope.valueObjRef[propertyName] && type != 'string') {
170                 scope.valueObjRef[propertyName] = JSON.parse(scope.valueObjRef[propertyName]);
171             }
172         };
173
174
175     };
176
177     public static factory = (DataTypesService:DataTypesService,
178                              PropertyNameValidationPattern:RegExp,
179                              ValidationUtils:ValidationUtils)=> {
180         return new SelectDataTypeFieldsStructureDirective(DataTypesService, PropertyNameValidationPattern, ValidationUtils);
181     };
182 }
183
184 SelectDataTypeFieldsStructureDirective.factory.$inject = ['Sdc.Services.DataTypesService', 'PropertyNameValidationPattern', 'ValidationUtils'];