cb16ffa2b48b4157a4e19859b327f7c2e3e1a1b3
[sdc.git] / catalog-ui / src / app / directives / property-types / data-type-fields-structure / data-type-fields-structure.ts
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 /**
22  * Created by obarda on 1/27/2016.
23  */
24 'use strict';
25 import * as _ from "lodash";
26 import {DataTypesService} from "app/services";
27 import { ValidationUtils } from "app/utils";
28 import { DataTypePropertyModel } from "app/models/data-type-properties";
29 import { DataTypesMap} from "app/models";
30
31 export interface IDataTypeFieldsStructureScope extends ng.IScope {
32     parentFormObj:ng.IFormController;
33     dataTypeProperties:Array<DataTypePropertyModel>;
34     typeName:string;
35     valueObjRef:any;
36     propertyNameValidationPattern:RegExp;
37     fieldsPrefixName:string;
38     readOnly:boolean;
39     currentTypeDefaultValue:any;
40     types:DataTypesMap;
41     expandByDefault:boolean;
42     expand:boolean;
43     expanded:boolean;
44     dataTypesService:DataTypesService;
45     constraints:string[];
46
47     expandAndCollapse():void;
48     getValidationPattern(type:string):RegExp;
49     validateIntRange(value:string):boolean;
50     onValueChange(propertyName:string, type:string):void
51     inputOnValueChange(property:any):void;
52 }
53
54
55 export class DataTypeFieldsStructureDirective implements ng.IDirective {
56
57     
58
59     constructor(private DataTypesService:DataTypesService,
60                 private PropertyNameValidationPattern:RegExp,
61                 private ValidationUtils:ValidationUtils) {
62     }
63
64     constraints: string[];
65
66     scope = {
67         valueObjRef: '=',
68         typeName: '=',
69         parentFormObj: '=',
70         fieldsPrefixName: '=',
71         readOnly: '=',
72         defaultValue: '@',
73         types: '=',
74         expandByDefault: '='        
75     };
76
77     restrict = 'E';
78     replace = true;
79     template = ():string => {
80         return require('./data-type-fields-structure.html');
81     };
82     //public types=Utils.Constants.PROPERTY_DATA.TYPES;
83
84     //get data type properties array and return object with the properties and their default value
85     //(for example: get: [{name:"prop1",defaultValue:1 ...},{name:"prop2", defaultValue:"bla bla" ...}]
86     //              return: {prop1: 1, prop2: "bla bla"}
87     private getDefaultValue = (dataTypeProperties:Array<DataTypePropertyModel>):any => {
88         let defaultValue = {};
89         for (let i = 0; i < dataTypeProperties.length; i++) {
90             if (dataTypeProperties[i].type != 'string') {
91                 if (!angular.isUndefined(dataTypeProperties[i].defaultValue)) {
92                     defaultValue[dataTypeProperties[i].name] = JSON.parse(dataTypeProperties[i].defaultValue);
93                 }
94             } else {
95                 defaultValue[dataTypeProperties[i].name] = dataTypeProperties[i].defaultValue;
96             }
97         }
98         return defaultValue;
99     };
100
101
102     private initDataOnScope = (scope:any, $attr:any):void => {
103         scope.dataTypesService = this.DataTypesService;
104         scope.dataTypeProperties = this.getDataTypeProperties(scope.typeName, scope.types);
105         if ($attr.defaultValue) {
106             scope.currentTypeDefaultValue = JSON.parse($attr.defaultValue);
107         } else {
108             scope.currentTypeDefaultValue = this.getDefaultValue(scope.dataTypeProperties);
109         }
110
111         if (!scope.valueObjRef) {
112             scope.valueObjRef = {};
113         }
114
115         _.forEach(scope.currentTypeDefaultValue, (value, key)=> {
116             if (angular.isUndefined(scope.valueObjRef[key])) {
117                 if (typeof scope.currentTypeDefaultValue[key] == 'object') {
118                     angular.copy(scope.currentTypeDefaultValue[key], scope.valueObjRef[key]);
119                 } else {
120                     scope.valueObjRef[key] = scope.currentTypeDefaultValue[key];
121                 }
122             }
123         });
124     };
125     
126     private getDataTypeProperties = (dataTypeName:string, typesInModel:DataTypesMap):Array<DataTypePropertyModel> => {
127         let properties = typesInModel[dataTypeName].properties || [];
128         if (typesInModel[dataTypeName].derivedFromName != "tosca.datatypes.Root") {
129             properties = this.getDataTypeProperties(typesInModel[dataTypeName].derivedFromName, typesInModel).concat(properties);
130         }
131         return properties;
132     };
133
134     private rerender = (scope:any):void => {
135         scope.expanded = false;
136         scope.expand = false;
137         if (scope.expandByDefault) {
138             scope.expandAndCollapse();
139         }
140     };
141
142     link = (scope:IDataTypeFieldsStructureScope, element:any, $attr:any) => {
143         scope.propertyNameValidationPattern = this.PropertyNameValidationPattern;
144
145         scope.$watchCollection('[typeName,fieldsPrefixName]', (newData:any):void => {
146             this.rerender(scope);
147         });
148
149
150         scope.expandAndCollapse = ():void => {
151             if (!scope.expanded) {
152                 this.initDataOnScope(scope, $attr);
153                 scope.expanded = true;
154             }
155             scope.expand = !scope.expand;
156         };
157
158         scope.getValidationPattern = (type:string):RegExp => {
159             return this.ValidationUtils.getValidationPattern(type);
160         };
161
162         scope.validateIntRange = (value:string):boolean => {
163             return !value || this.ValidationUtils.validateIntRange(value);
164         };
165
166         scope.onValueChange = (propertyName:string, type:string,):void => {
167             scope.valueObjRef[propertyName] = !angular.isUndefined(scope.valueObjRef[propertyName]) ? scope.valueObjRef[propertyName] : scope.currentTypeDefaultValue[propertyName];
168             if (scope.valueObjRef[propertyName] && type != 'string') {
169                 scope.valueObjRef[propertyName] = JSON.parse(scope.valueObjRef[propertyName]);
170             }
171         };
172
173         scope.inputOnValueChange = (property:any) => {
174             if (property.constraints){
175                 // this.constraints = property.constraints[0].validValues;
176             }
177             
178             let value = !scope.parentFormObj[scope.fieldsPrefixName + property.name].$error.pattern
179                 && ('integer' == property.type && scope.parentFormObj[scope.fieldsPrefixName + property.name].$setValidity('pattern', scope.validateIntRange(scope.valueObjRef[property.name]))
180                 || scope.onValueChange(property.name, (property.simpleType || property.type)));
181             return value;
182         }
183     };
184
185     public static factory = (DataTypesService:DataTypesService,
186                              PropertyNameValidationPattern:RegExp,
187                              ValidationUtils:ValidationUtils)=> {
188         return new DataTypeFieldsStructureDirective(DataTypesService, PropertyNameValidationPattern, ValidationUtils);
189     };
190 }
191
192 DataTypeFieldsStructureDirective.factory.$inject = ['Sdc.Services.DataTypesService', 'PropertyNameValidationPattern', 'ValidationUtils'];