[SDC] rebase 1710 code
[sdc.git] / catalog-ui / src / app / models / properties-inputs / property-fe-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 import {SchemaPropertyGroupModel, SchemaProperty} from '../aschema-property';
22 import { PROPERTY_DATA, PROPERTY_TYPES } from 'app/utils';
23 import { FilterPropertiesAssignmentData, PropertyBEModel, DerivedPropertyType, DerivedFEPropertyMap, DerivedFEProperty } from 'app/models';
24
25
26 export class PropertyFEModel extends PropertyBEModel {
27
28     expandedChildPropertyId: string;
29     flattenedChildren:  Array<DerivedFEProperty>;
30     isDeclared: boolean;
31     isDisabled: boolean;
32     isSelected: boolean;
33     isSimpleType: boolean; //for convenience only - we can really just check if derivedDataType == derivedPropertyTypes.SIMPLE to know if the prop is simple
34     propertiesName: string;
35     uniqueId: string;
36     valueObj: any; //this is the only value we relate to in the html templates
37     derivedDataType: DerivedPropertyType;
38
39     constructor(property: PropertyBEModel){
40         super(property);
41         this.isSimpleType = PROPERTY_DATA.SIMPLE_TYPES.indexOf(this.type) > -1;
42         this.setNonDeclared();
43         this.derivedDataType = this.getDerivedPropertyType();
44         this.flattenedChildren = [];
45         this.propertiesName = this.name;
46     }
47
48
49     public getJSONValue = (): string => {
50         //If type is JSON, need to try parsing it before we stringify it so that it appears property in TOSCA - change per Bracha due to AMDOCS
51         //TODO: handle this.derivedDataType == DerivedPropertyType.MAP
52         if (this.derivedDataType == DerivedPropertyType.LIST && this.schema.property.type == PROPERTY_TYPES.JSON) {
53             try {
54                 return JSON.stringify(this.valueObj.map(item => (typeof item == 'string')? JSON.parse(item) : item));
55             } catch (e){}
56         }
57
58         return (this.derivedDataType == DerivedPropertyType.SIMPLE) ? this.valueObj : JSON.stringify(this.valueObj);
59     }
60
61     public setNonDeclared = (childPath?: string): void => {
62         if (!childPath) { //un-declaring a child prop
63             this.isDeclared = false;
64         } else {
65             let childProp: DerivedFEProperty = this.flattenedChildren.find(child => child.propertiesName == childPath);
66             childProp.isDeclared = false;
67         }
68     }
69
70     public setAsDeclared = (childNameToDeclare?:string): void => {
71         if (!childNameToDeclare) { //declaring a child prop
72             this.isSelected = false;
73             this.isDeclared = true;
74         } else {
75             let childProp: DerivedFEProperty = this.flattenedChildren.find(child => child.propertiesName == childNameToDeclare);
76             if (!childProp) { console.log("ERROR: Unabled to find child: " + childNameToDeclare, this); return; }
77             childProp.isSelected = false;
78             childProp.isDeclared = true;
79         }
80     }
81
82     //For expand-collapse functionality - used within HTML template
83     public updateExpandedChildPropertyId = (childPropertyId: string): void => {
84         if (childPropertyId.lastIndexOf('#') > -1) {
85             this.expandedChildPropertyId = (this.expandedChildPropertyId == childPropertyId) ? (childPropertyId.substring(0, childPropertyId.lastIndexOf('#'))) : childPropertyId;
86         } else {
87             this.expandedChildPropertyId = this.name;
88         }
89     }
90
91     public getIndexOfChild = (childPropName: string): number => {
92         return this.flattenedChildren.findIndex(prop => prop.propertiesName.indexOf(childPropName) === 0);
93     }
94
95     public getCountOfChildren = (childPropName: string):number => {
96         let matchingChildren:Array<DerivedFEProperty> = this.flattenedChildren.filter(prop => prop.propertiesName.indexOf(childPropName) === 0) || [];
97         return matchingChildren.length;
98     }
99
100     // public getListIndexOfChild = (childPropName: string): number => { //gets list of siblings and then the index within that list
101     //     this.flattenedChildren.filter(prop => prop.parentName == item.parentName).map(prop => prop.propertiesName).indexOf(item.propertiesName)
102     // }
103
104     /* Updates parent valueObj when a child prop's value has changed */
105     public childPropUpdated = (childProp: DerivedFEProperty): void => {
106         let parentNames = this.getParentNamesArray(childProp.propertiesName, []);
107         if (parentNames.length) {
108             _.set(this.valueObj, parentNames.join('.'), childProp.valueObj);
109         }
110     };
111
112     /* Returns array of individual parents for given prop path, with list/map UUIDs replaced with index/mapkey */
113     public getParentNamesArray = (parentPropName: string, parentNames?: Array<string>): Array<string> => {
114         if (parentPropName.indexOf("#") == -1) { return parentNames; } //finished recursing parents. return
115
116         let parentProp: DerivedFEProperty = this.flattenedChildren.find(prop => prop.propertiesName === parentPropName);
117         let nameToInsert: string = parentProp.name;
118
119         if (parentProp.isChildOfListOrMap) {
120             if (parentProp.derivedDataType == DerivedPropertyType.MAP) {
121                 nameToInsert = parentProp.mapKey;
122             } else { //LIST
123                 let siblingProps = this.flattenedChildren.filter(prop => prop.parentName == parentProp.parentName).map(prop => prop.propertiesName);
124                 nameToInsert = siblingProps.indexOf(parentProp.propertiesName).toString();
125             }
126         }
127
128         parentNames.splice(0, 0, nameToInsert); //add prop name to array
129         return this.getParentNamesArray(parentProp.parentName, parentNames); //continue recursing
130     }
131
132
133 }