Sync Integ to Master
[sdc.git] / catalog-ui / src / app / view-models / forms / attribute-form / attribute-from-view-model.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 'use strict';
22 import * as _ from "lodash";
23 import {AttributeModel, Component} from "app/models";
24 import {IMapRegex, ValidationUtils, FormState, PROPERTY_TYPES} from "app/utils";
25
26 export interface IEditAttributeModel {
27     attribute:AttributeModel;
28     types:Array<string>;
29     simpleTypes:Array<string>;
30 }
31
32 export class attributeValue {//in order to solve DE226783, we update the value on another obj
33     value:string;
34 }
35
36 interface IAttributeFormViewModelScope extends ng.IScope {
37     $$childTail:any;
38     forms:any;
39     editForm:ng.IFormController;
40     footerButtons:Array<any>;
41     isService:boolean;
42     editAttributeModel:IEditAttributeModel;
43     modalInstanceAttribute:ng.ui.bootstrap.IModalServiceInstance;
44     isNew:boolean;
45     listRegex:IMapRegex;
46     mapRegex:IMapRegex;
47     propertyNameValidationPattern:RegExp;
48     commentValidationPattern:RegExp;
49     isLoading:boolean;
50     validationPattern:RegExp;
51     attributeValue:attributeValue;
52
53     save():void;
54     close():void;
55     onTypeChange():void;
56     onValueChange():void;
57     isAttributeValueOwner():boolean;
58     validateIntRange(value:string):boolean;
59     validateUniqueKeys(viewValue:string):boolean;
60     getValidationTranslate():string;
61     showSchema():boolean;
62     isSchemaEditable():boolean;
63     validateName():void;
64 }
65
66 export class AttributeFormViewModel {
67
68     static '$inject' = [
69         '$scope',
70         '$uibModalInstance',
71         'attribute',
72         'ValidationUtils',
73         'CommentValidationPattern',
74         'PropertyNameValidationPattern',
75         'component'
76     ];
77
78     private formState:FormState;
79
80
81     constructor(private $scope:IAttributeFormViewModelScope,
82                 private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance,
83                 private attribute:AttributeModel,
84                 private ValidationUtils:ValidationUtils,
85                 private CommentValidationPattern:RegExp,
86                 private PropertyNameValidationPattern:RegExp,
87                 private component:Component) {
88         this.formState = angular.isDefined(attribute.name) ? FormState.UPDATE : FormState.CREATE;
89         this.initScope();
90     }
91
92     private initResource = ():void => {
93         this.$scope.editAttributeModel.attribute = new AttributeModel(this.attribute);
94         if (this.$scope.editAttributeModel.types.indexOf(this.attribute.type) === -1) {//attribute defaulte type is string too?
95             this.attribute.type = "string";
96         }
97     };
98
99     private initEditAttributeModel = ():void => {
100         this.$scope.editAttributeModel = {
101             attribute: null,
102             types: ['integer', 'string', 'float', 'boolean', 'list', 'map'],
103             simpleTypes: ['integer', 'string', 'float', 'boolean']
104         };
105
106         this.initResource();
107     };
108
109     private initScope = ():void => {
110
111         //scope attributes
112         this.$scope.forms = {};
113         this.$scope.propertyNameValidationPattern = this.PropertyNameValidationPattern;
114         this.$scope.commentValidationPattern = this.CommentValidationPattern;
115
116         this.$scope.modalInstanceAttribute = this.$uibModalInstance;
117         this.$scope.listRegex = this.ValidationUtils.getPropertyListPatterns();
118         this.$scope.mapRegex = this.ValidationUtils.getPropertyMapPatterns();
119
120         this.$scope.isNew = (this.formState === FormState.CREATE);
121         this.$scope.isLoading = false;
122         this.$scope.attributeValue = new attributeValue();
123
124         this.initEditAttributeModel();
125         this.setValidationPattern();
126
127         //scope methods
128         this.$scope.save = ():void => {
129             if (!this.$scope.forms.editForm.$invalid) {
130                 let attribute:AttributeModel = this.$scope.editAttributeModel.attribute;
131                 this.$scope.editAttributeModel.attribute.description = this.ValidationUtils.stripAndSanitize(this.$scope.editAttributeModel.attribute.description);
132                 ////if read only - just closes the modal
133                 if (this.$scope.editAttributeModel.attribute.readonly && !this.$scope.isAttributeValueOwner()) {
134                     this.$uibModalInstance.close();
135                     return;
136                 }
137                 this.$scope.isLoading = true;
138                 let onAttributeFaild = (response):void => {
139                     console.info('onFaild', response);
140                     this.$scope.isLoading = false;
141                 };
142
143                 let onAttributeSuccess = (attributeFromBE:AttributeModel):void => {
144                     console.info('onAttributeResourceSuccess : ', attributeFromBE);
145                     this.$scope.isLoading = false;
146                     this.$uibModalInstance.close();
147                 };
148
149                 //in case we have uniqueId we call update method
150                 if (this.$scope.isAttributeValueOwner()) {
151                     attribute.value = this.$scope.attributeValue.value;
152                     this.component.updateInstanceAttribute(attribute).then(onAttributeSuccess, onAttributeFaild);
153                 } else {
154                     attribute.defaultValue = this.$scope.attributeValue.value;
155                     this.component.addOrUpdateAttribute(attribute).then(onAttributeSuccess, onAttributeFaild);
156                 }
157             }
158         };
159
160         this.$scope.close = ():void => {
161             this.$uibModalInstance.close();
162         };
163
164         this.$scope.validateName = ():void => {
165             let existsAttr:AttributeModel = _.find(this.component.attributes, (attribute:AttributeModel) => {
166                 return attribute.name === this.$scope.editAttributeModel.attribute.name;
167             });
168             if (existsAttr) {
169                 this.$scope.forms.editForm["attributeName"].$setValidity('nameExist', false);
170             } else {
171                 this.$scope.forms.editForm["attributeName"].$setValidity('nameExist', true);
172             }
173
174         };
175
176         this.$scope.onTypeChange = ():void => {
177             this.$scope.editAttributeModel.attribute.value = '';
178             this.$scope.editAttributeModel.attribute.defaultValue = '';
179             this.setValidationPattern();
180         };
181
182         this.$scope.isAttributeValueOwner = ():boolean=> {
183             return this.component.isService() || !!this.component.selectedInstance;
184         };
185
186         this.$scope.onValueChange = ():void => {
187             if (!this.$scope.editAttributeModel.attribute.value) {
188                 if (this.$scope.isAttributeValueOwner()) {
189                     this.$scope.editAttributeModel.attribute.value = this.$scope.editAttributeModel.attribute.defaultValue;
190                 }
191             }
192         };
193
194
195         this.$scope.validateUniqueKeys = (viewValue:string):boolean => {
196             if (this.$scope.editAttributeModel.attribute.type === 'map') {
197                 return this.ValidationUtils.validateUniqueKeys(viewValue);
198             }
199             else {
200                 return true; //always valid if not a map
201             }
202         };
203
204         this.$scope.validateIntRange = (value:string):boolean => {
205             return !value || this.ValidationUtils.validateIntRange(value);
206         };
207
208         this.$scope.isSchemaEditable = ():boolean => {
209             let schemaType = this.$scope.editAttributeModel.attribute.schema.property.type;
210             return this.$scope.editAttributeModel.simpleTypes.indexOf(schemaType) > -1 || !schemaType;
211         };
212
213         this.$scope.showSchema = ():boolean => {
214             return ['list', 'map'].indexOf(this.$scope.editAttributeModel.attribute.type) > -1;
215         };
216
217         this.$scope.getValidationTranslate = ():string => {
218             let result = "ATTRIBUTE_EDIT_PATTERN";
219             if (this.$scope.showSchema()) {
220
221                 result = "ATTRIBUTE_EDIT_" + this.$scope.editAttributeModel.attribute.type.toUpperCase();
222
223                 if (this.$scope.editAttributeModel.attribute.schema.property.type === PROPERTY_TYPES.STRING) {
224                     result += "_STRING";
225                 } else if (this.$scope.editAttributeModel.attribute.schema.property.type === PROPERTY_TYPES.BOOLEAN) {
226                     result += "_BOOLEAN";
227                 } else {
228                     result += "_GENERIC";
229                 }
230             }
231
232             return result;
233         };
234
235         // Add the done button at the footer.
236         this.$scope.footerButtons = [
237             {'name': 'Done', 'css': 'blue', 'callback': this.$scope.save},
238             {'name': 'Cancel', 'css': 'grey', 'callback': this.$scope.close}
239         ];
240
241         this.$scope.$watchCollection("forms.editForm.$invalid", (newVal, oldVal) => {
242             this.$scope.footerButtons[0].disabled = this.$scope.forms.editForm.$invalid;
243         });
244
245         this.$scope.attributeValue.value = this.$scope.isAttributeValueOwner() ? this.$scope.editAttributeModel.attribute.value : this.$scope.editAttributeModel.attribute.defaultValue;
246     };
247
248
249     private setValidationPattern = ():void => {
250
251         if (this.$scope.editAttributeModel.attribute.type === 'list') {
252             this.$scope.validationPattern = this.$scope.listRegex[this.$scope.editAttributeModel.attribute.schema.property.type];
253         }
254         else if (this.$scope.editAttributeModel.attribute.type === 'map') {
255             this.$scope.validationPattern = this.$scope.mapRegex[this.$scope.editAttributeModel.attribute.schema.property.type];
256         }
257         else {
258             this.$scope.validationPattern = this.ValidationUtils.getValidationPattern(this.$scope.editAttributeModel.attribute.type);
259         }
260
261     };
262 }