RIFT-14803: UI Composer: References should be dropdowns https://osm.etsi.org/gerrit...
[osm/UI.git] / skyquake / plugins / composer / src / src / libraries / model / DescriptorModelMetaProperty.js
1 /*
2 *
3 * Copyright 2016 RIFT.IO Inc
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18 /**
19 * Created by onvelocity on 1/27/16.
20 *
21 * This class provides utility methods for interrogating an instance of model uiState object.
22 */
23
24 'use strict';
25
26 import _ from 'lodash'
27 import guid from './../guid'
28 import changeCase from 'change-case'
29 import InstanceCounter from './../InstanceCounter'
30 import DescriptorModelFields from './DescriptorModelFields'
31 import DescriptorTemplateFactory from './DescriptorTemplateFactory'
32 import utils from '../utils'
33
34 export default {
35 isLeaf(property = {}) {
36 return /leaf|choice/.test(property.type);
37 },
38 isList(property = {}) {
39 return /list|leaf_list/.test(property.type);
40 },
41 isLeafList(property = {}) {
42 return property.type === 'leaf_list';
43 },
44 isLeafRef(property = {}) {
45 const type = property['data-type'] || {};
46 return type.hasOwnProperty('leafref');
47 },
48 isArray(property = {}) {
49 // give '1' or '0..N' or '0..1' or '0..5' determine if represents an array
50 // '0..1' is not an array
51 // '0..2' is an array
52 // '0..N' is an array
53 const cardinality = String(property.cardinality).toUpperCase();
54 const pos = cardinality.lastIndexOf('.') + 1;
55 const val = cardinality.substr(pos);
56 return val === 'N' || parseInt(val, 10) > 1;
57 },
58 isEnumeration(property = {}) {
59 const type = property['data-type'] || {};
60 return type.hasOwnProperty('enumeration');
61 },
62 isRequired(property = {}) {
63 return /^1/.test(property.cardinality);
64 },
65 isObject(property = {}) {
66 return !/^(leaf|leaf_list)$/.test(property.type);
67 },
68 isSimpleList(property = {}) {
69 return _.contains(DescriptorModelFields.simpleList, property.name);
70 },
71 isPrimativeDataType(property = {}) {
72 const Property = this;
73 return /string|int/.test(property['data-type']) || Property.isEnumeration(property) || Property.isGuid(property);
74 },
75 defaultValue(property = {}) {
76 if (property.defaultValue) {
77 return property.defaultValue;
78 }
79 if (this.isObject(property)) {
80 return {};
81 }
82 return '';
83 },
84 getContainerMethod(property, container, methodName) {
85 const name = changeCase.camel(methodName + '-' + property.name);
86 if (typeof container[name] === 'function') {
87 return container[name].bind(container);
88 }
89 },
90 getContainerCreateMethod(property, container) {
91 const name = changeCase.camel('create-' + property.name);
92 if (typeof container[name] === 'function') {
93 return container[name].bind(container);
94 }
95 },
96 containerHasCreateMethod(container, property = {}) {
97 const find = changeCase.camel('create-' + property.name);
98 return typeof container[find] === 'function';
99 },
100 getEnumeration(property = {}, value) {
101 const enumeration = property['data-type'].enumeration.enum;
102 if (typeof enumeration === 'string') {
103 return [{name: enumeration, value: enumeration, isSelected: String(value) === enumeration}];
104 }
105 return Object.keys(enumeration).map(enumName => {
106 let enumValue = enumName;
107 // warn we only support named enums and systematically ignore enum values
108 //const enumObj = enumeration[enumName];
109 //if (enumObj) {
110 // enumValue = enumObj.value || enumName;
111 //}
112 return {name: enumName, value: enumValue, isSelected: String(enumValue) === String(value)};
113 });
114 },
115 getLeafRef(property = {}, path, value, fullFieldKey, transientCatalogs, container) {
116 const leafRefPath = property['data-type']['leafref']['path'];
117
118 const transientCatalogHash = {};
119
120 transientCatalogs.map((catalog) => {
121 transientCatalogHash[catalog.type + '-catalog'] = {};
122 transientCatalogHash[catalog.type + '-catalog'][catalog.type] = catalog['descriptors'];
123 });
124
125 let leafRefPathValues = utils.resolveLeafRefPath(transientCatalogHash, leafRefPath, fullFieldKey, path, container);
126
127 let leafRefObjects = [];
128
129 leafRefPathValues && leafRefPathValues.map((leafRefPathValue) => {
130 leafRefObjects.push({
131 name: leafRefPathValue,
132 value: leafRefPathValue,
133 isSelected: String(leafRefPathValue) === String(value)
134 });
135 });
136
137 return leafRefObjects;
138 },
139 isGuid(property = {}) {
140 const type = property['data-type'];
141 if (typeof type === 'object' && type.leafref && type.leafref.path) {
142 return /\bid$/.test(type.leafref.path);
143 }
144 return /uuid/.test(property['data-type']);
145 },
146 createModelInstance(property) {
147 const Property = this;
148 const defaultValue = Property.defaultValue.bind(this);
149 function createModel(uiState, parentMeta) {
150 const model = {};
151 if (Property.isLeaf(uiState)) {
152 if (uiState.name === 'name') {
153 return changeCase.param(parentMeta.name) + '-' + InstanceCounter.count(parentMeta[':qualified-type']);
154 }
155 if (_.isArray(parentMeta.key) && _.contains(parentMeta.key, uiState.name)) {
156 if (/uuid/.test(uiState['data-type'])) {
157 return guid();
158 }
159 if (uiState['data-type'] === 'string') {
160 const prefix = uiState.name.replace('id', '');
161 return (prefix ? changeCase.param(prefix) + '-' : '') + guid(5);
162 }
163 if (/int/.test(uiState['data-type'])) {
164 return InstanceCounter.count(uiState[':qualified-type']);
165 }
166 }
167 return defaultValue(uiState);
168 } else if (Property.isList(uiState)) {
169 return [];
170 } else {
171 uiState.properties.forEach(p => {
172 model[p.name] = createModel(p, uiState);
173 });
174 }
175 return model;
176 }
177 if (property) {
178 if (Property.isPrimativeDataType(property)) {
179 return defaultValue(property);
180 }
181 if (property.type === 'leaf') {
182 return defaultValue(property);
183 }
184 if (/list/.test(property.type)) {
185 property.type = 'container';
186 }
187 const modelInstance = createModel(property, property);
188 modelInstance.uiState = {type: property.name};
189 const modelFragment = DescriptorTemplateFactory.createModelForType(property[':qualified-type'] || property.name) || {};
190 Object.assign(modelInstance, modelFragment);
191 return modelInstance;
192 }
193 }
194 }