3 PROPERTY_TYPES, ModalsHandler, ValidationUtils, PROPERTY_VALUE_CONSTRAINTS, FormState, PROPERTY_DATA} from "app/utils";
4 import {DataTypesService} from "app/services";
5 import {PropertyModel, DataTypesMap, Component} from "app/models";
7 export interface IEditPropertyModel {
8 property:PropertyModel;
10 simpleTypes:Array<string>;
13 interface IPropertyFormViewModelScope extends ng.IScope {
15 editForm:ng.IFormController;
16 footerButtons:Array<any>;
20 validationPattern:RegExp;
21 propertyNameValidationPattern:RegExp;
22 commentValidationPattern:RegExp;
23 editPropertyModel:IEditPropertyModel;
24 modalInstanceProperty:ng.ui.bootstrap.IModalServiceInstance;
25 currentPropertyIndex:number;
26 isLastProperty:boolean;
28 nonPrimitiveTypes:Array<string>;
29 dataTypes:DataTypesMap;
30 isTypeDataType:boolean;
32 isPropertyValueOwner:boolean;
34 validateJson(json:string):boolean;
35 save(doNotCloseModal?:boolean):void;
36 getValidationPattern(type:string):RegExp;
37 validateIntRange(value:string):boolean;
40 onSchemaTypeChange():void;
41 onTypeChange(resetSchema:boolean):void;
43 delete(property:PropertyModel):void;
46 isSimpleType(typeName:string):boolean;
47 getDefaultValue():any;
50 export class PropertyFormViewModel {
54 'Sdc.Services.DataTypesService',
58 'PropertyNameValidationPattern',
59 'CommentValidationPattern',
66 'isPropertyValueOwner'
69 private formState:FormState;
71 constructor(private $scope:IPropertyFormViewModelScope,
72 private DataTypesService:DataTypesService,
73 private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance,
74 private property:PropertyModel,
75 private ValidationPattern:RegExp,
76 private PropertyNameValidationPattern:RegExp,
77 private CommentValidationPattern:RegExp,
78 private ValidationUtils:ValidationUtils,
79 private component:Component,
80 private $filter:ng.IFilterService,
81 private ModalsHandler:ModalsHandler,
82 private filteredProperties:Array<PropertyModel>,
83 private $timeout:ng.ITimeoutService,
84 private isPropertyValueOwner:boolean) {
86 this.formState = angular.isDefined(property.name) ? FormState.UPDATE : FormState.CREATE;
90 private initResource = ():void => {
91 this.$scope.editPropertyModel.property = new PropertyModel(this.property);
92 this.$scope.editPropertyModel.property.type = this.property.type ? this.property.type : null;
94 this.initAddOnLabels();
97 //init property add-ons labels that show up at the left side of the input.
98 private initAddOnLabels = () => {
99 if (this.$scope.editPropertyModel.property.name == 'network_role' && this.$scope.isService) {
100 //the server sends back the normalized name. Remove it (to prevent interference with validation) and set the addon label to the component name directly.
101 //Note: this cant be done in properties.ts because we dont have access to the component
102 if (this.$scope.editPropertyModel.property.value) {
103 let splitProp = this.$scope.editPropertyModel.property.value.split(new RegExp(this.component.normalizedName + '.', "gi"));
104 this.$scope.editPropertyModel.property.value = splitProp.pop();
106 this.$scope.editPropertyModel.property.addOn = this.component.name;
110 private initEditPropertyModel = ():void => {
111 this.$scope.editPropertyModel = {
113 types: PROPERTY_DATA.TYPES,
114 simpleTypes: PROPERTY_DATA.SIMPLE_TYPES
120 private initForNotSimpleType = ():void => {
121 let property = this.$scope.editPropertyModel.property;
122 this.$scope.isTypeDataType = this.DataTypesService.isDataTypeForPropertyType(this.$scope.editPropertyModel.property);
123 if (property.type && this.$scope.editPropertyModel.simpleTypes.indexOf(property.type) == -1) {
124 if (!(property.value || property.defaultValue)) {
125 switch (property.type) {
126 case PROPERTY_TYPES.MAP:
127 this.$scope.myValue = {'': null};
129 case PROPERTY_TYPES.LIST:
130 this.$scope.myValue = [];
133 this.$scope.myValue = {};
136 this.$scope.myValue = JSON.parse(property.value || property.defaultValue);
141 private setMaxLength = ():void => {
142 switch (this.$scope.editPropertyModel.property.type) {
143 case PROPERTY_TYPES.MAP:
144 case PROPERTY_TYPES.LIST:
145 this.$scope.maxLength = this.$scope.editPropertyModel.property.schema.property.type == PROPERTY_TYPES.JSON ?
146 PROPERTY_VALUE_CONSTRAINTS.JSON_MAX_LENGTH :
147 PROPERTY_VALUE_CONSTRAINTS.MAX_LENGTH;
149 case PROPERTY_TYPES.JSON:
150 this.$scope.maxLength = PROPERTY_VALUE_CONSTRAINTS.JSON_MAX_LENGTH;
153 this.$scope.maxLength =PROPERTY_VALUE_CONSTRAINTS.MAX_LENGTH;
158 private initScope = ():void => {
161 this.$scope.forms = {};
162 this.$scope.validationPattern = this.ValidationPattern;
163 this.$scope.propertyNameValidationPattern = this.PropertyNameValidationPattern;
164 this.$scope.commentValidationPattern = this.CommentValidationPattern;
165 this.$scope.isLoading = false;
166 this.$scope.isNew = (this.formState === FormState.CREATE);
167 this.$scope.isService = this.component.isService();
168 this.$scope.modalInstanceProperty = this.$uibModalInstance;
169 this.$scope.currentPropertyIndex = _.findIndex(this.filteredProperties, i=> i.name == this.property.name);
170 this.$scope.isLastProperty = this.$scope.currentPropertyIndex == (this.filteredProperties.length - 1);
171 this.$scope.dataTypes = this.DataTypesService.getAllDataTypes();
172 this.$scope.isPropertyValueOwner = this.isPropertyValueOwner;
173 this.initEditPropertyModel();
175 this.$scope.nonPrimitiveTypes = _.filter(Object.keys(this.$scope.dataTypes), (type:string)=> {
176 return this.$scope.editPropertyModel.types.indexOf(type) == -1;
178 this.initForNotSimpleType();
181 this.$scope.validateJson = (json:string):boolean => {
185 return this.ValidationUtils.validateJson(json);
190 this.$scope.save = (doNotCloseModal?:boolean):void => {
191 let property:PropertyModel = this.$scope.editPropertyModel.property;
192 this.$scope.editPropertyModel.property.description = this.ValidationUtils.stripAndSanitize(this.$scope.editPropertyModel.property.description);
193 //if read only - or no changes made - just closes the modal
194 //need to check for property.value changes manually to detect if map properties deleted
195 if ((this.$scope.editPropertyModel.property.readonly && !this.$scope.isPropertyValueOwner)
196 || (!this.$scope.forms.editForm.$dirty && angular.equals(JSON.stringify(this.$scope.myValue), this.$scope.editPropertyModel.property.value))) {
197 this.$uibModalInstance.close();
201 this.$scope.isLoading = true;
203 let onPropertyFaild = (response):void => {
204 console.info('onFaild', response);
205 this.$scope.isLoading = false;
208 let onPropertySuccess = (propertyFromBE:PropertyModel):void => {
209 console.info('onPropertyResourceSuccess : ', propertyFromBE);
210 this.$scope.isLoading = false;
212 if (!doNotCloseModal) {
213 this.$uibModalInstance.close(propertyFromBE);
215 this.$scope.forms.editForm.$setPristine();
216 this.$scope.editPropertyModel.property = new PropertyModel();
220 //in case we have uniqueId we call update method
221 if (this.$scope.isPropertyValueOwner) {
222 if (!this.$scope.editPropertyModel.property.simpleType && !this.$scope.isSimpleType(property.type)) {
223 let myValueString:string = JSON.stringify(this.$scope.myValue);
224 property.value = myValueString;
226 this.component.updateInstanceProperty(property).then(onPropertySuccess, onPropertyFaild);
228 if (!this.$scope.editPropertyModel.property.simpleType && !this.$scope.isSimpleType(property.type)) {
229 let myValueString:string = JSON.stringify(this.$scope.myValue);
230 property.defaultValue = myValueString;
232 this.$scope.editPropertyModel.property.defaultValue = this.$scope.editPropertyModel.property.value;
234 this.component.addOrUpdateProperty(property).then(onPropertySuccess, onPropertyFaild);
238 this.$scope.getPrev = ():void=> {
239 this.property = this.filteredProperties[--this.$scope.currentPropertyIndex];
241 this.initForNotSimpleType();
242 this.$scope.isLastProperty = false;
245 this.$scope.getNext = ():void=> {
246 this.property = this.filteredProperties[++this.$scope.currentPropertyIndex];
248 this.initForNotSimpleType();
249 this.$scope.isLastProperty = this.$scope.currentPropertyIndex == (this.filteredProperties.length - 1);
252 this.$scope.isSimpleType = (typeName:string):boolean=> {
253 return typeName && this.$scope.editPropertyModel.simpleTypes.indexOf(typeName) != -1;
256 this.$scope.showSchema = ():boolean => {
257 return [PROPERTY_TYPES.LIST, PROPERTY_TYPES.MAP].indexOf(this.$scope.editPropertyModel.property.type) > -1;
260 this.$scope.getValidationPattern = (type:string):RegExp => {
261 return this.ValidationUtils.getValidationPattern(type);
264 this.$scope.validateIntRange = (value:string):boolean => {
265 return !value || this.ValidationUtils.validateIntRange(value);
268 this.$scope.close = ():void => {
269 this.$uibModalInstance.close();
272 // put default value when instance value is empty
273 this.$scope.onValueChange = ():void => {
274 if (!this.$scope.editPropertyModel.property.value) {
275 if (this.$scope.isPropertyValueOwner) {
276 this.$scope.editPropertyModel.property.value = this.$scope.editPropertyModel.property.defaultValue;
281 // Add the done button at the footer.
282 this.$scope.footerButtons = [
283 {'name': 'Save', 'css': 'blue', 'callback': this.$scope.save},
284 {'name': 'Cancel', 'css': 'grey', 'callback': this.$scope.close}
287 this.$scope.$watch("forms.editForm.$invalid", (newVal, oldVal) => {
288 this.$scope.footerButtons[0].disabled = this.$scope.forms.editForm.$invalid;
291 this.$scope.getDefaultValue = ():any => {
292 return this.$scope.isPropertyValueOwner ? this.$scope.editPropertyModel.property.defaultValue : null;
295 this.$scope.onTypeChange = ():void => {
296 this.$scope.editPropertyModel.property.value = '';
297 this.$scope.editPropertyModel.property.defaultValue = '';
299 this.initForNotSimpleType();
302 this.$scope.onSchemaTypeChange = ():void => {
303 if (this.$scope.editPropertyModel.property.type == PROPERTY_TYPES.MAP) {
304 this.$scope.myValue = {'': null};
305 } else if (this.$scope.editPropertyModel.property.type == PROPERTY_TYPES.LIST) {
306 this.$scope.myValue = [];
311 this.$scope.delete = (property:PropertyModel):void => {
312 let onOk = ():void => {
313 this.component.deleteProperty(property.uniqueId).then(
317 let title:string = this.$filter('translate')("PROPERTY_VIEW_DELETE_MODAL_TITLE");
318 let message:string = this.$filter('translate')("PROPERTY_VIEW_DELETE_MODAL_TEXT", "{'name': '" + property.name + "'}");
319 this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk);