[SDC-29] catalog 1707 rebase commit.
[sdc.git] / catalog-ui / src / app / directives / property-types / type-map / type-map-directive.ts
1 /**
2  * Created by rcohen on 9/15/2016.
3  */
4 'use strict';
5 import {ValidationUtils, PROPERTY_TYPES} from "app/utils";
6 import {DataTypesService} from "app/services";
7 import {SchemaProperty} from "app/models";
8
9 export interface ITypeMapScope extends ng.IScope {
10     parentFormObj:ng.IFormController;
11     schemaProperty:SchemaProperty;
12     isSchemaTypeDataType:boolean;
13     valueObjRef:any;
14     mapKeys:Array<string>;//array of map keys
15     MapKeyValidationPattern:RegExp;
16     fieldsPrefixName:string;
17     readOnly:boolean;
18     mapDefaultValue:any;
19     maxLength:number;
20
21     getValidationPattern(type:string):RegExp;
22     validateIntRange(value:string):boolean;
23     changeKeyOfMap(newKey:string, index:number, fieldName:string):void;
24     deleteMapItem(index:number):void;
25     addMapItemFields():void;
26     parseToCorrectType(objectOfValues:any, locationInObj:string, type:string):void;
27     getNumber(num:number):Array<any>;
28 }
29
30
31 export class TypeMapDirective implements ng.IDirective {
32
33     constructor(private DataTypesService:DataTypesService,
34                 private MapKeyValidationPattern:RegExp,
35                 private ValidationUtils:ValidationUtils,
36                 private $timeout:ng.ITimeoutService) {
37     }
38
39     scope = {
40         valueObjRef: '=',//ref to map object in the parent value object
41         schemaProperty: '=',//get the schema.property object
42         parentFormObj: '=',//ref to parent form (get angular form object)
43         fieldsPrefixName: '=',//prefix for form fields names
44         readOnly: '=',//is form read only
45         defaultValue: '@',//this map default value
46         maxLength: '='
47     };
48
49     restrict = 'E';
50     replace = true;
51     template = ():string => {
52         return require('./type-map-directive.html');
53     };
54
55     link = (scope:ITypeMapScope, element:any, $attr:any) => {
56         scope.MapKeyValidationPattern = this.MapKeyValidationPattern;
57
58         //reset valueObjRef and mapKeys when schema type is changed
59         scope.$watchCollection('schemaProperty.type', (newData:any):void => {
60             scope.isSchemaTypeDataType = this.DataTypesService.isDataTypeForSchemaType(scope.schemaProperty);
61             if (scope.valueObjRef) {
62                 scope.mapKeys = Object.keys(scope.valueObjRef);
63             }
64         });
65
66         //when user brows between properties in "edit property form"
67         scope.$watchCollection('fieldsPrefixName', (newData:any):void => {
68             if (!scope.valueObjRef) {
69                 scope.valueObjRef = {};
70             }
71             scope.mapKeys = Object.keys(scope.valueObjRef);
72
73             if ($attr.defaultValue) {
74                 scope.mapDefaultValue = JSON.parse($attr.defaultValue);
75             }
76         });
77
78         //return dummy array in order to prevent rendering map-keys ng-repeat again when a map key is changed
79         scope.getNumber = (num:number):Array<any> => {
80             return new Array(num);
81         };
82
83         scope.getValidationPattern = (type:string):RegExp => {
84             return this.ValidationUtils.getValidationPattern(type);
85         };
86
87         scope.validateIntRange = (value:string):boolean => {
88             return !value || this.ValidationUtils.validateIntRange(value);
89         };
90
91         scope.changeKeyOfMap = (newKey:string, index:number, fieldName:string):void => {
92             let oldKey = Object.keys(scope.valueObjRef)[index];
93             let existsKeyIndex = Object.keys(scope.valueObjRef).indexOf(newKey);
94             if (existsKeyIndex > -1 && existsKeyIndex != index) {
95                 scope.parentFormObj[fieldName].$setValidity('keyExist', false);
96             } else {
97                 scope.parentFormObj[fieldName].$setValidity('keyExist', true);
98                 if (!scope.parentFormObj[fieldName].$invalid) {
99                     let newObj = {};
100                     angular.forEach(scope.valueObjRef,function(value:any,key:string){
101                         if(key == oldKey){
102                             newObj[newKey] = value;
103                         }else{
104                             newObj[key] = value;
105                         }
106                     });
107                     scope.valueObjRef = newObj;
108                 }
109             }
110         };
111
112         scope.deleteMapItem = (index:number):void=> {
113             delete scope.valueObjRef[scope.mapKeys[index]];
114             scope.mapKeys.splice(index, 1);
115             if (!scope.mapKeys.length) {//only when user removes all pairs of key-value fields - put the default
116                 if (scope.mapDefaultValue) {
117                     angular.copy(scope.mapDefaultValue, scope.valueObjRef);
118                     scope.mapKeys = Object.keys(scope.valueObjRef);
119                 }
120             }
121         };
122
123         scope.addMapItemFields = ():void => {
124             scope.valueObjRef[''] = null;
125             scope.mapKeys = Object.keys(scope.valueObjRef);
126         };
127
128         scope.parseToCorrectType = (objectOfValues:any, locationInObj:string, type:string):void => {
129             if (objectOfValues[locationInObj] && type != PROPERTY_TYPES.STRING) {
130                 objectOfValues[locationInObj] = JSON.parse(objectOfValues[locationInObj]);
131             }
132         }
133     };
134
135     public static factory = (DataTypesService:DataTypesService,
136                              MapKeyValidationPattern:RegExp,
137                              ValidationUtils:ValidationUtils,
138                              $timeout:ng.ITimeoutService)=> {
139         return new TypeMapDirective(DataTypesService, MapKeyValidationPattern, ValidationUtils, $timeout);
140     };
141 }
142
143 TypeMapDirective.factory.$inject = ['Sdc.Services.DataTypesService', 'MapKeyValidationPattern', 'ValidationUtils', '$timeout'];