aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui/app/scripts/utils
diff options
context:
space:
mode:
authorMichael Lando <ml636r@att.com>2017-02-19 10:28:42 +0200
committerMichael Lando <ml636r@att.com>2017-02-19 10:51:01 +0200
commit451a3400b76511393c62a444f588a4ed15f4a549 (patch)
treee4f5873a863d1d3e55618eab48b83262f874719d /catalog-ui/app/scripts/utils
parent5abfe4e1fb5fae4bbd5fbc340519f52075aff3ff (diff)
Initial OpenECOMP SDC commit
Change-Id: I0924d5a6ae9cdc161ae17c68d3689a30d10f407b Signed-off-by: Michael Lando <ml636r@att.com>
Diffstat (limited to 'catalog-ui/app/scripts/utils')
-rw-r--r--catalog-ui/app/scripts/utils/artifacts-utils.ts121
-rw-r--r--catalog-ui/app/scripts/utils/change-lifecycle-state-handler.ts151
-rw-r--r--catalog-ui/app/scripts/utils/common-utils.ts81
-rw-r--r--catalog-ui/app/scripts/utils/component-factory.ts181
-rw-r--r--catalog-ui/app/scripts/utils/component-instance-factory.ts85
-rw-r--r--catalog-ui/app/scripts/utils/constants.ts247
-rw-r--r--catalog-ui/app/scripts/utils/dictionary/dictionary.ts257
-rw-r--r--catalog-ui/app/scripts/utils/file-utils.ts73
-rw-r--r--catalog-ui/app/scripts/utils/functions.ts58
-rw-r--r--catalog-ui/app/scripts/utils/menu-handler.ts145
-rw-r--r--catalog-ui/app/scripts/utils/modals-handler.ts275
-rw-r--r--catalog-ui/app/scripts/utils/prototypes.ts155
-rw-r--r--catalog-ui/app/scripts/utils/validation-utils.ts173
13 files changed, 2002 insertions, 0 deletions
diff --git a/catalog-ui/app/scripts/utils/artifacts-utils.ts b/catalog-ui/app/scripts/utils/artifacts-utils.ts
new file mode 100644
index 0000000000..439a0e98d0
--- /dev/null
+++ b/catalog-ui/app/scripts/utils/artifacts-utils.ts
@@ -0,0 +1,121 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+/// <reference path="../references"/>
+module Sdc.Utils {
+ export class ArtifactsUtils {
+
+ static '$inject' = [
+ '$filter',
+ '$templateCache',
+ '$modal'
+ ];
+
+ constructor(private $filter:ng.IFilterService,
+ private $templateCache:ng.ITemplateCacheService,
+ private $modal:ng.ui.bootstrap.IModalService) {
+
+ }
+
+ public getArtifactTypeByState(currentState:string):string {
+ switch (currentState) {
+ case "workspace.composition.lifecycle":
+ return "interface";
+ case "workspace.composition.api":
+ return "api";
+ case "workspace.composition.deployment":
+ return "deployment";
+ default:
+ return "normal";
+ }
+ }
+
+ public getTitle(artifactType:string, selectedComponent:Models.Components.Component):string {
+ switch (artifactType) {
+ case "interface":
+ return "Lifecycle Management";
+ case "api":
+ return "API Artifacts";
+ case "deployment":
+ return "Deployment Artifacts";
+ default:
+ if (!selectedComponent) {
+ return "";
+ } else {
+ return this.$filter("resourceName")(selectedComponent.name) + ' Artifacts';
+ }
+ }
+ }
+
+ public setArtifactType = (artifact:Models.ArtifactModel, artifactType:string):void => {
+ switch (artifactType) {
+ case "api":
+ artifact.artifactGroupType = 'SERVICE_API';
+ break;
+ case "deployment":
+ artifact.artifactGroupType = 'DEPLOYMENT';
+ break;
+ default:
+ artifact.artifactGroupType = 'INFORMATIONAL';
+ break;
+ }
+ };
+
+ public isLicenseType = (artifactType:string) :boolean => {
+ let isLicense:boolean = false;
+
+ if(Utils.Constants.ArtifactType.VENDOR_LICENSE === artifactType || Utils.Constants.ArtifactType.VF_LICENSE === artifactType) {
+ isLicense = true;
+ }
+
+ return isLicense;
+ };
+
+ public removeArtifact = (artifact:Models.ArtifactModel, artifactsArr:Array<Models.ArtifactModel>):void => {
+
+ if (!artifact.mandatory && (Utils.Constants.ArtifactGroupType.INFORMATION == artifact.artifactGroupType ||
+ Utils.Constants.ArtifactGroupType.DEPLOYMENT == artifact.artifactGroupType)) {
+ _.remove(artifactsArr, {uniqueId: artifact.uniqueId});
+ }
+ else {
+ let artifactToDelete = _.find(artifactsArr, {uniqueId: artifact.uniqueId});
+
+ delete artifactToDelete.esId;
+ delete artifactToDelete.description;
+ delete artifactToDelete.artifactName;
+ delete artifactToDelete.apiUrl;
+ }
+ };
+
+ public addAnotherAfterSave(scope:Sdc.ViewModels.IArtifactResourceFormViewModelScope) {
+ let newArtifact = new Models.ArtifactModel();
+ this.setArtifactType(newArtifact, scope.artifactType);
+ scope.editArtifactResourceModel.artifactResource = newArtifact;
+
+ scope.forms.editForm['description'].$setPristine();
+ if(scope.forms.editForm['artifactLabel']){
+ scope.forms.editForm['artifactLabel'].$setPristine();
+ }
+ if(scope.forms.editForm['type']){
+ scope.forms.editForm['type'].$setPristine();
+ }
+
+ }
+ }
+}
diff --git a/catalog-ui/app/scripts/utils/change-lifecycle-state-handler.ts b/catalog-ui/app/scripts/utils/change-lifecycle-state-handler.ts
new file mode 100644
index 0000000000..7722a899b9
--- /dev/null
+++ b/catalog-ui/app/scripts/utils/change-lifecycle-state-handler.ts
@@ -0,0 +1,151 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+/**
+ * Created by obarda on 2/11/2016.
+ */
+/// <reference path="../references"/>
+module Sdc.Utils {
+
+ export class ChangeLifecycleStateHandler {
+
+ static '$inject' = [
+ 'sdcConfig',
+ 'sdcMenu',
+ 'ComponentFactory',
+ '$templateCache',
+ '$filter',
+ '$modal',
+ 'ModalsHandler'
+ ];
+
+ constructor(
+ private sdcConfig:Models.IAppConfigurtaion,
+ private sdcMenu:Models.IAppMenu,
+ private ComponentFactory: Sdc.Utils.ComponentFactory,
+ private $templateCache:ng.ITemplateCacheService,
+ private $filter:ng.IFilterService,
+ private $modal:ng.ui.bootstrap.IModalService,
+ private ModalsHandler: Utils.ModalsHandler
+
+ ) {
+
+ }
+
+ changeLifecycleState = (component:Models.Components.Component, data:any, scope:any, onSuccessCallback?: Function, onErrorCallback?: Function):void => {
+
+ let self = this;
+
+ let getContacts = (component:Models.Components.Component):string =>{
+ let testers = this.sdcConfig.testers;
+ let result:string = testers[component.componentType][component.categories[0].name]?
+ testers[component.componentType][component.categories[0].name]:
+ testers[component.componentType]['default'];
+ return result;
+ };
+
+ let onSuccess = (newComponent:Models.Components.Component):void => {
+ //scope.isLoading = false;
+ console.info(component.componentType.toLowerCase + ' change state ' , newComponent);
+ if(onSuccessCallback) {
+ onSuccessCallback(self.ComponentFactory.createComponent(newComponent));
+ }
+ };
+
+ let onError = (error):void => {
+ scope.isLoading = false;
+ console.info('Failed to changeLifecycleState to ', data.url);
+ if(onErrorCallback) {
+ onErrorCallback(error);
+ }
+ };
+
+ let comment:Models.AsdcComment = new Models.AsdcComment();
+ if (data.alertModal) {
+ // Show alert dialog if defined in menu.json
+ //-------------------------------------------------
+ let onOk = (confirmationText):void => {
+ comment.userRemarks = confirmationText;
+ scope.isLoading = true;
+ component.changeLifecycleState(data.url, comment).then(onSuccess, onError);
+ };
+
+ let onCancel = ():void => {
+ console.info('Cancel pressed');
+ scope.isLoading = false;
+ };
+
+ let modalTitle = this.sdcMenu.alertMessages[data.alertModal].title;
+ let modalMessage = this.sdcMenu.alertMessages[data.alertModal].message.format([component.componentType.toLowerCase()]);
+ this.ModalsHandler.openAlertModal(modalTitle, modalMessage).then(onOk, onCancel);
+ } else if (data.confirmationModal) {
+ // Show confirmation dialog if defined in menu.json
+ //-------------------------------------------------
+ let onOk = (confirmationText):void => {
+ comment.userRemarks = confirmationText;
+ scope.isLoading = true;
+ component.changeLifecycleState(data.url, comment).then(onSuccess, onError);
+ };
+
+ let onCancel = ():void => {
+ console.info('Cancel pressed');
+ scope.isLoading = false;
+ };
+
+ let modalTitle = this.sdcMenu.confirmationMessages[data.confirmationModal].title;
+ let modalMessage = this.sdcMenu.confirmationMessages[data.confirmationModal].message.format([component.componentType.toLowerCase()]);
+ let modalShowComment = this.sdcMenu.confirmationMessages[data.confirmationModal].showComment;
+ this.ModalsHandler.openConfirmationModal(modalTitle, modalMessage, modalShowComment).then(onOk, onCancel);
+
+ } else if (data.emailModal) {
+ // Show email dialog if defined in menu.json
+ //-------------------------------------------------
+ let onOk = (resource):void => {
+ if (resource){
+ onSuccess(resource);
+ } else {
+ onError("Error changing life cycle state");
+ }
+ };
+
+ let onCancel = ():void => {
+ scope.isLoading = false;
+ };
+
+ let emailModel: ViewModels.IEmailModalModel = <ViewModels.IEmailModalModel>{};
+ emailModel.email = <ViewModels.IEmailModalModel_Email>{};
+ emailModel.data = <ViewModels.IEmailModalModel_Data>{};
+ emailModel.title = this.$filter('translate')("EMAIL_MODAL_TITLE");
+ emailModel.email.to = getContacts(component);
+ emailModel.email.subject = this.$filter('translate')("EMAIL_MODAL_SUBJECT", "{'entityName': '" + this.$filter('resourceName')(component.name) + "','entityVersion': '" + component.version + "'}");
+ emailModel.email.message = '';
+ emailModel.data.component = component;
+ emailModel.data.stateUrl = data.url;
+
+ this.ModalsHandler.openEmailModal(emailModel).then(onOk, onCancel);
+
+ } else {
+ // Submit to server only (no modal is shown).
+ scope.isLoading = true;
+ component.changeLifecycleState(data.url, comment).then(onSuccess, onError);
+ }
+
+ }
+ }
+}
diff --git a/catalog-ui/app/scripts/utils/common-utils.ts b/catalog-ui/app/scripts/utils/common-utils.ts
new file mode 100644
index 0000000000..aef6b9908d
--- /dev/null
+++ b/catalog-ui/app/scripts/utils/common-utils.ts
@@ -0,0 +1,81 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+/**
+ * Created by obarda on 6/30/2016.
+ */
+/// <reference path="../references.ts"/>
+module Sdc.Utils {
+
+ export class CommonUtils {
+
+ static initProperties(propertiesObj:Array<Sdc.Models.PropertyModel>, uniqueId?:string):Array<Sdc.Models.PropertyModel> {
+
+ let properties = new Array<Sdc.Models.PropertyModel>();
+ if (propertiesObj) {
+ _.forEach(propertiesObj, (property:Sdc.Models.PropertyModel):void => {
+ if (uniqueId) {
+ property.readonly = property.parentUniqueId != uniqueId;
+ }
+ properties.push(new Sdc.Models.PropertyModel(property));
+ });
+ }
+ return properties;
+ };
+
+ static initAttributes(attributesObj:Array<Sdc.Models.AttributeModel>, uniqueId?:string):Array<Sdc.Models.AttributeModel> {
+
+ let attributes = new Array<Sdc.Models.AttributeModel>();
+ if (attributesObj) {
+ _.forEach(attributesObj, (attribute:Sdc.Models.AttributeModel):void => {
+ if (uniqueId) {
+ attribute.readonly = attribute.parentUniqueId != uniqueId;
+ }
+ attributes.push(new Sdc.Models.AttributeModel(attribute));
+ });
+ }
+ return attributes;
+ };
+
+ static initComponentInstances(componentInstanceObj:Array<Models.ComponentsInstances.ResourceInstance>):Array<Models.ComponentsInstances.ResourceInstance> {
+
+ let componentInstances = new Array<Models.ComponentsInstances.ResourceInstance>();
+ if (componentInstanceObj) {
+ _.forEach(componentInstanceObj, (instance:Models.ComponentsInstances.ResourceInstance):void => {
+ componentInstances.push(Utils.ComponentInstanceFactory.createComponentInstance(instance));
+ });
+ }
+ return componentInstances;
+ };
+
+ static initModules(moduleArrayObj:Array<Models.Module>):Array<Models.Module> {
+
+ let modules = new Array<Models.Module>();
+
+ if (moduleArrayObj) {
+ _.forEach(moduleArrayObj, (module:Models.Module):void => {
+ if(module.type === "org.openecomp.groups.VfModule"){
+ modules.push(new Models.Module(module));
+ }
+ });
+ }
+ return modules;
+ };
+ }
+}
diff --git a/catalog-ui/app/scripts/utils/component-factory.ts b/catalog-ui/app/scripts/utils/component-factory.ts
new file mode 100644
index 0000000000..1bb139dc45
--- /dev/null
+++ b/catalog-ui/app/scripts/utils/component-factory.ts
@@ -0,0 +1,181 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+/**
+ * Created by obarda on 2/8/2016.
+ */
+/// <reference path="../references"/>
+module Sdc.Utils {
+ 'use strict';
+ import Resource = Sdc.Models.Components.Resource;
+
+ export class ComponentFactory {
+
+ static '$inject' = [
+ 'Sdc.Services.Components.ResourceService',
+ 'Sdc.Services.Components.ServiceService',
+ 'Sdc.Services.Components.ProductService',
+ 'Sdc.Services.CacheService',
+ '$q'
+ ];
+
+ constructor(
+ private ResourceService:Services.Components.ResourceService,
+ private ServiceService:Services.Components.ServiceService,
+ private ProductService:Services.Components.ProductService,
+ private cacheService:Services.CacheService,
+ private $q: ng.IQService) {
+ }
+
+ public createComponent = (component:Models.Components.Component):Models.Components.Component => {
+ let newComponent:Models.Components.Component;
+ switch (component.componentType) {
+
+ case 'SERVICE':
+ newComponent = new Models.Components.Service(this.ServiceService, this.$q, <Models.Components.Service> component);
+ break;
+
+ case 'RESOURCE':
+ newComponent = new Models.Components.Resource(this.ResourceService, this.$q, <Models.Components.Resource> component);
+ break;
+
+ case 'PRODUCT':
+ newComponent = new Models.Components.Product(this.ProductService, this.$q, <Models.Components.Product> component);
+ break;
+ }
+ return newComponent;
+ };
+
+ public createProduct = (product:Models.Components.Product):Models.Components.Product => {
+ let newProduct:Models.Components.Product = new Models.Components.Product(this.ProductService, this.$q, <Models.Components.Product> product);
+ return newProduct;
+ };
+
+ public createService = (service:Models.Components.Service):Models.Components.Service => {
+ let newService:Models.Components.Service = new Models.Components.Service(this.ServiceService, this.$q, <Models.Components.Service> service);
+ return newService;
+ };
+
+ public createResource = (resource:Models.Components.Resource):Models.Components.Resource => {
+ let newResource:Models.Components.Resource = new Models.Components.Resource(this.ResourceService, this.$q, <Models.Components.Resource> resource);
+ return newResource;
+ };
+
+ public createFromCsarComponent = (csar:Models.ICsarComponent):Models.Components.Component => {
+ let newResource:Sdc.Models.Components.Resource = <Sdc.Models.Components.Resource>this.createEmptyComponent(Sdc.Utils.Constants.ComponentType.RESOURCE);
+ newResource.name = csar.vspName;
+
+ /**
+ * Onboarding CSAR contains category and sub category that are uniqueId.
+ * Need to find the category and sub category and extract the name from them.
+ * First concat all sub categories to one array.
+ * Then find the selected sub category and category.
+ * @type {any}
+ */
+ let availableCategories = angular.copy(this.cacheService.get('resourceCategories'));
+ let allSubs = [];
+ _.each(availableCategories, (main:Models.IMainCategory)=>{
+ if (main.subcategories) {
+ allSubs = allSubs.concat(main.subcategories);
+ }
+ });
+
+ let selectedCategory:Models.IMainCategory = _.find(availableCategories, function(main:Models.IMainCategory){
+ return main.uniqueId === csar.category;
+ });
+
+ let selectedSubCategory:Models.ISubCategory = _.find(allSubs,(sub:Models.ISubCategory)=>{
+ return sub.uniqueId === csar.subCategory;
+ });
+
+ // Build the categories and sub categories array (same format as component category)
+ let categories:Array<Models.IMainCategory> = new Array();
+ let subcategories:Array<Models.ISubCategory> = new Array();
+ if (selectedCategory && selectedSubCategory) {
+ subcategories.push(selectedSubCategory);
+ selectedCategory.subcategories = subcategories;
+ categories.push(selectedCategory);
+ }
+
+ // Fill the component with details from CSAR
+ newResource.selectedCategory = selectedCategory && selectedSubCategory ? selectedCategory.name + "_#_" + selectedSubCategory.name : '';
+ newResource.categories = categories;
+ newResource.vendorName = csar.vendorName;
+ newResource.vendorRelease = csar.vendorRelease;
+ newResource.csarUUID = csar.packageId;
+ newResource.csarPackageType = csar.packageType;
+ newResource.csarVersion = csar.version;
+ newResource.packageId = csar.packageId;
+ newResource.description = csar.description;
+ return newResource;
+ };
+
+ public createEmptyComponent = (componentType: string):Models.Components.Component => {
+ let newComponent:Models.Components.Component;
+
+ switch (componentType) {
+
+ case Utils.Constants.ComponentType.SERVICE:
+ newComponent = new Models.Components.Service(this.ServiceService, this.$q);
+ break;
+
+ case Utils.Constants.ComponentType.RESOURCE:
+ case Utils.Constants.ResourceType.VF:
+ case Utils.Constants.ResourceType.VL:
+ case Utils.Constants.ResourceType.VFC:
+ case Utils.Constants.ResourceType.CP:
+ newComponent = new Models.Components.Resource(this.ResourceService, this.$q);
+ break;
+
+ case Utils.Constants.ComponentType.PRODUCT:
+ newComponent = new Models.Components.Product(this.ProductService, this.$q);
+ break;
+ }
+ newComponent.componentType = componentType;
+ newComponent.tags = [];
+ newComponent.icon = Utils.Constants.DEFAULT_ICON;
+ return newComponent;
+ };
+
+
+ public getServiceFromServer = (componentId: string): ng.IPromise<Models.Components.Service> => {
+ let service: Models.Components.Service = <Models.Components.Service>this.createEmptyComponent(Utils.Constants.ComponentType.SERVICE);
+ service.setUniqueId(componentId);
+ return service.getComponent();
+ };
+
+ public getResourceFromServer = (componentId: string): ng.IPromise<Models.Components.Resource> => {
+ let resource: Models.Components.Resource = <Models.Components.Resource>this.createEmptyComponent(Utils.Constants.ComponentType.RESOURCE);
+ resource.setUniqueId(componentId);
+ return resource.getComponent();
+ };
+
+ public getComponentFromServer = (componentType: string, componentId: string): ng.IPromise<Models.Components.Component> => {
+ let newComponent: Models.Components.Component = this.createEmptyComponent(componentType);
+ newComponent.setUniqueId(componentId);
+ return newComponent.getComponent();
+ };
+
+ public createComponentOnServer = (componentObject:Models.Components.Component):ng.IPromise<Models.Components.Component> => {
+ let component: Models.Components.Component = this.createComponent(componentObject);
+ return component.createComponentOnServer();
+
+ };
+ }
+}
diff --git a/catalog-ui/app/scripts/utils/component-instance-factory.ts b/catalog-ui/app/scripts/utils/component-instance-factory.ts
new file mode 100644
index 0000000000..5f698aa46c
--- /dev/null
+++ b/catalog-ui/app/scripts/utils/component-instance-factory.ts
@@ -0,0 +1,85 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+/**
+ * Created by obarda on 3/7/2016.
+ */
+/**
+ * Created by obarda on 2/8/2016.
+ */
+/// <reference path="../references"/>
+module Sdc.Utils {
+ 'use strict';
+
+ export class ComponentInstanceFactory {
+
+ static createComponentInstance(componentInstance:Models.ComponentsInstances.ComponentInstance):Models.ComponentsInstances.ComponentInstance {
+ let newComponentInstance:Models.ComponentsInstances.ComponentInstance;
+ switch (componentInstance.originType) {
+ case 'SERVICE':
+ newComponentInstance = new Models.ComponentsInstances.ServiceInstance(componentInstance);
+ break;
+
+ case 'PRODUCT':
+ newComponentInstance = new Models.ComponentsInstances.ProductInstance(componentInstance);
+ break;
+
+ default :
+ newComponentInstance = new Models.ComponentsInstances.ResourceInstance(componentInstance);
+ break;
+ }
+ return newComponentInstance;
+ };
+
+ public createEmptyComponentInstance = (componentInstanceType?: string):Models.ComponentsInstances.ComponentInstance => {
+ let newComponentInstance:Models.ComponentsInstances.ComponentInstance;
+ switch (componentInstanceType) {
+ case 'SERVICE':
+ newComponentInstance = new Models.ComponentsInstances.ServiceInstance();
+ break;
+
+ case 'PRODUCT':
+ newComponentInstance = new Models.ComponentsInstances.ProductInstance();
+ break;
+
+ default :
+ newComponentInstance = new Models.ComponentsInstances.ResourceInstance();
+ break;
+ }
+ return newComponentInstance;
+ };
+
+ public createComponentInstanceFromComponent = (component: Models.Components.Component):Models.ComponentsInstances.ComponentInstance => {
+ let newComponentInstance:Models.ComponentsInstances.ComponentInstance = this.createEmptyComponentInstance(component.componentType);
+ newComponentInstance.uniqueId = component.uniqueId + (new Date()).getTime();
+ newComponentInstance.posX = 0;
+ newComponentInstance.posY = 0;
+ newComponentInstance.name = component.name;
+ newComponentInstance.componentVersion = component.version;
+ newComponentInstance.originType = component.getComponentSubType();
+ //new component instance -> req. & cap. are added on successful instance creation
+ newComponentInstance.requirements = component.requirements;
+ newComponentInstance.capabilities = component.capabilities;
+ newComponentInstance.icon = component.icon;
+ newComponentInstance.componentUid = component.uniqueId;
+ return newComponentInstance;
+ };
+
+ }
+}
diff --git a/catalog-ui/app/scripts/utils/constants.ts b/catalog-ui/app/scripts/utils/constants.ts
new file mode 100644
index 0000000000..6db1edf29d
--- /dev/null
+++ b/catalog-ui/app/scripts/utils/constants.ts
@@ -0,0 +1,247 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+/**
+ * Created by obarda on 2/18/2016.
+ */
+/// <reference path="../references"/>
+module Sdc.Utils.Constants {
+
+ import SuiteOrSpec = jasmine.SuiteOrSpec;
+ export let DEFAULT_ICON = 'defaulticon';
+ export let CP_END_POINT = 'CpEndPoint';
+ export let CHANGE_COMPONENT_CSAR_VERSION_FLAG = 'changeComponentCsarVersion';
+ export let IMAGE_PATH = '';
+
+ export class ComponentType {
+ static SERVICE = 'SERVICE';
+ static RESOURCE = 'RESOURCE';
+ static PRODUCT = 'PRODUCT';
+ }
+
+ export class ResourceType {
+ static VF = 'VF';
+ static VL = 'VL';
+ static CP = 'CP';
+ static VFC = 'VFC';
+ }
+
+ export class ComponentState {
+ static CERTIFICATION_IN_PROGRESS = 'CERTIFICATION_IN_PROGRESS';
+ static CERTIFIED = 'CERTIFIED';
+ static NOT_CERTIFIED_CHECKOUT = 'NOT_CERTIFIED_CHECKOUT';
+ static NOT_CERTIFIED_CHECKIN = 'NOT_CERTIFIED_CHECKIN';
+ static READY_FOR_CERTIFICATION = 'READY_FOR_CERTIFICATION';
+ }
+
+ export class DistributionStatus {
+ DISTRIBUTION_NOT_APPROVED = 'DISTRIBUTION_NOT_APPROVED';
+ DISTRIBUTION_APPROVED = 'DISTRIBUTION_APPROVED';
+ DISTRIBUTED = 'DISTRIBUTED';
+ DISTRIBUTION_REJECTED = 'DISTRIBUTION_REJECTED';
+ }
+
+ export class ArtifactGroupType {
+ static DEPLOYMENT = "DEPLOYMENT";
+ static INFORMATION = "INFORMATIONAL";
+ static SERVICE_API = "SERVICE_API";
+ }
+
+ export class ArtifactType {
+ static HEAT = "HEAT";
+ static VF_LICENSE = "VF_LICENSE";
+ static VENDOR_LICENSE = "VENDOR_LICENSE";
+ static THIRD_PARTY_RESERVED_TYPES = { WORKFLOW:"WORKFLOW",
+ NETWORK_CALL_FLOW:"NETWORK_CALL_FLOW",
+ AAI_SERVICE_MODEL:"AAI_SERVICE_MODEL",
+ AAI_VF_MODEL:"AAI_VF_MODEL",
+ AAI_VF_MODULE_MODEL:"AAI_VF_MODULE_MODEL",
+ AAI_VF_INSTANCE_MODEL:"AAI_VF_INSTANCE_MODEL"};
+ static TOSCA = { TOSCA_TEMPLATE:"TOSCA_TEMPLATE", TOSCA_CSAR:"TOSCA_CSAR"};
+ }
+
+ export class SEVERITY {
+ public static DEBUG = 'DEBUG';
+ public static INFO = 'INFO';
+ public static WARNING = 'WARNING';
+ public static ERROR = 'ERROR';
+ }
+
+ export class PROPERTY_TYPES {
+ public static STRING = 'string';
+ public static INTEGER = 'integer';
+ public static FLOAT = 'float';
+ public static BOOLEAN = 'boolean';
+ public static JSON = 'json';
+ public static MAP = 'map';
+ public static LIST = 'list';
+ }
+
+ export class SOURCES {
+ public static A_AND_AI = 'A&AI';
+ public static ORDER = 'Order';
+ public static RUNTIME = 'Runtime';
+ }
+
+ export class PROPERTY_DATA {
+ public static TYPES = [PROPERTY_TYPES.STRING, PROPERTY_TYPES.INTEGER, PROPERTY_TYPES.FLOAT, PROPERTY_TYPES.BOOLEAN, PROPERTY_TYPES.JSON, PROPERTY_TYPES.LIST, PROPERTY_TYPES.MAP];
+ public static SIMPLE_TYPES = [PROPERTY_TYPES.STRING, PROPERTY_TYPES.INTEGER, PROPERTY_TYPES.FLOAT, PROPERTY_TYPES.BOOLEAN, PROPERTY_TYPES.JSON];
+ public static SOURCES = [SOURCES.A_AND_AI, SOURCES.ORDER, SOURCES.RUNTIME];
+ }
+
+ export class PROPERTY_VALUE_CONSTRAINTS {
+ public static MAX_LENGTH = 100;
+ public static JSON_MAX_LENGTH = 4096;
+ }
+
+ export class Role {
+ public static ADMIN = 'ADMIN';
+ public static DESIGNER = 'DESIGNER';
+ public static PRODUCT_STRATEGIST = 'PRODUCT_STRATEGIST';
+ public static PRODUCT_MANAGER = 'PRODUCT_MANAGER';
+ public static TESTER = 'TESTER';
+ public static OPS = 'OPS';
+ public static GOVERNOR = 'GOVERNOR';
+ }
+
+ export enum FormState{
+ CREATE,
+ UPDATE,
+ IMPORT,
+ VIEW
+ }
+
+ export class WorkspaceMode {
+ public static CREATE = 'create';
+ public static EDIT = 'edit';
+ public static IMPORT = 'import';
+ public static VIEW = 'view';
+ }
+
+ export class ImagesUrl {
+ public static RESOURCE_ICONS = '/styles/images/resource-icons/';
+ public static SERVICE_ICONS = '/styles/images/service-icons/';
+ public static SELECTED_UCPE_INSTANCE = '/styles/images/resource-icons/selectedUcpeInstance.png';
+ public static SELECTED_CP_INSTANCE = '/styles/images/resource-icons/selectedCPInstance.png';
+ public static SELECTED_VL_INSTANCE = '/styles/images/resource-icons/selectedVLInstance.png';
+ public static CANVAS_PLUS_ICON = '/styles/images/resource-icons/canvasPlusIcon.png';
+ public static MODULE_ICON = '/styles/images/resource-icons/module.png';
+ public static OPEN_MODULE_ICON = '/styles/images/resource-icons/openModule.png';
+ public static OPEN_MODULE_HOVER_ICON = '/styles/images/resource-icons/openModuleHover.png';
+ public static CLOSE_MODULE_ICON = '/styles/images/resource-icons/closeModule.png';
+ public static CLOSE_MODULE_HOVER_ICON = '/styles/images/resource-icons/closeModuleHover.png';
+ }
+
+ export class ModalType {
+ static STANDARD = 'standard';
+ static ERROR = 'error';
+ static ALERT = 'alert';
+ }
+
+ export class GraphColors {
+ public static NOT_CERTIFIED_LINK = 'rgb(218,31,61)';
+ public static VL_LINK = 'rgb(216,216,216)';
+ public static ACTIVE_LINK = '#30bdf2';
+ public static BASE_LINK = 'rgb(55,55,55)';
+ public static NODE_BACKGROUND_COLOR = 'rgba(46, 162, 157, 0.24)';
+ public static NODE_SHADOW_COLOR = 'rgba(198, 230, 228, 0.7)';
+ public static NODE_OVERLAPPING_BACKGROUND_COLOR = 'rgba(179, 10, 60, 0.24)';
+ public static NODE_OVERLAPPING_SHADOW_COLOR = 'rgba(236, 194, 206, 0.7)';
+ public static NODE_UCPE_CP = '#9063cd';
+ public static NODE_UCPE = '#fbfbfb';
+ public static NODE_SELECTED_BORDER_COLOR = '#30bdf2';
+ }
+
+ export class GraphTransactionLogText {
+ public static REMOVE_TEMP_LINK = "remove tempLink";
+ public static DELETE_LINK = "delete link";
+ public static ADD_LINK = "delete link";
+ public static ADD_NODE = "adding node";
+ }
+
+ export class GraphUIObjects {
+ public static LINK_MENU_HEIGHT = 420;
+ public static TOP_HEADER_HEIGHT = 200;
+ public static TOOLTIP_OFFSET_X = 50;
+ public static TOOLTIP_OFFSET_Y = 145;
+ public static TOOLTIP_LINK_OFFSET_X = 35;
+ public static TOOLTIP_LINK_OFFSET_Y = 75;
+ public static MENU_LINK_VL_HEIGHT_OFFSET = 250;
+ public static MENU_LINK_VL_WIDTH_OFFSET = 200;
+ public static MENU_LINK_SIMPLE_HEIGHT_OFFSET = 180;
+ public static MENU_LINK_SIMPLE_WIDTH_OFFSET = 130;
+ public static DIAGRAM_RIGHT_WIDTH_OFFSET = 248;
+ public static DIAGRAM_HEADER_OFFSET = 103;
+ public static DIAGRAM_PALETTE_WIDTH_OFFSET = 247;
+
+ }
+
+ export class States {
+ public static WORKSPACE_GENERAL = 'workspace.general';
+ public static WORKSPACE_ICONS = 'workspace.icons';
+ public static WORKSPACE_ACTIVITY_LOG = 'workspace.activity_log';
+ public static WORKSPACE_DEPLOYMENT_ARTIFACTS = 'workspace.deployment_artifacts';
+ public static WORKSPACE_PROPERTIES = 'workspace.properties';
+ public static WORKSPACE_SERVICE_INPUTS = 'workspace.service_inputs';
+ public static WORKSPACE_RESOURCE_INPUTS = 'workspace.resource_inputs';
+ public static WORKSPACE_ATTRIBUTES = 'workspace.attributes';
+ public static WORKSPACE_HIERARCHY = 'workspace.hierarchy';
+ public static WORKSPACE_INFORMATION_ARTIFACTS = 'workspace.information_artifacts';
+ public static WORKSPACE_TOSCA_ARTIFACTS = 'workspace.tosca_artifacts';
+ public static WORKSPACE_COMPOSITION = 'workspace.composition';
+ public static WORKSPACE_NETWORK_CALL_FLOW = 'workspace.network_call_flow';
+ public static WORKSPACE_MANAGEMENT_WORKFLOW = 'workspace.management_workflow';
+ public static WORKSPACE_DEPLOYMENT = 'workspace.deployment';
+ public static WORKSPACE_DISTRIBUTION = 'workspace.distribution';
+ public static WORKSPACE_REQUIREMENTS_AND_CAPABILITIES = 'workspace.reqAndCap';
+ }
+
+ export class EVENTS {
+ static RESOURCE_LEFT_PALETTE_UPDATE_EVENT = "resourceLeftPanelUpdateEvent";
+ static SERVICE_LEFT_PALETTE_UPDATE_EVENT = "serviceLeftPanelUpdateEvent";
+ static PRODUCT_LEFT_PALETTE_UPDATE_EVENT = "productLeftPanelUdateEvent";
+ static VL_LEFT_PALETTE_UPDATE_EVENT = "vlLeftPanelUdateEvent";
+ static ON_CSAR_LOADING = "onCsarLoading";
+ static DOWNLOAD_ARTIFACT_FINISH_EVENT = "downloadArtifactFinishEvent";
+ static ON_WORKSPACE_SAVE_BUTTON_CLICK = "onWorkspaceSaveButtonClick";
+ static ON_WORKSPACE_SAVE_BUTTON_SUCCESS = "onWorkspaceSaveButtonSuccess";
+ static ON_WORKSPACE_SAVE_BUTTON_ERROR = "onWorkspaceSaveButtonError";
+
+ //Loader events
+ static SHOW_LOADER_EVENT = "showLoaderEvent";
+ static HIDE_LOADER_EVENT = "hideLoaderEvent";
+ }
+
+ export class GRAPH_EVENTS {
+ static ON_NODE_SELECTED = "onNodeSelected";
+ static ON_GRAPH_BACKGROUND_CLICKED = "onGraphBackgroundClicked";
+ static ON_PALETTE_COMPONENT_HOVER_IN = 'onPaletteComponentHoverIn';
+ static ON_PALETTE_COMPONENT_HOVER_OUT = 'onPaletteComponentHoverOut';
+ static ON_PALETTE_COMPONENT_DRAG_START = 'onPaletteComponentDragStart';
+ static ON_PALETTE_COMPONENT_DRAG_ACTION = 'onPaletteComponentDragAction';
+ static ON_COMPONENT_INSTANCE_NAME_CHANGED = 'onComponentInstanceNameChanged';
+ static ON_DELETE_COMPONENT_INSTANCE = 'onDeleteComponentInstance';
+ static ON_DELETE_MULTIPLE_COMPONENTS = 'onDeleteMultipleComponents';
+ static ON_DELETE_EDGE = 'onDeleteEdge';
+ static ON_INSERT_NODE_TO_UCPE = 'onInsertNodeToUCPE';
+ static ON_REMOVE_NODE_FROM_UCPE = 'onRemoveNodeFromUCPE';
+ static ON_VERSION_CHANGED = 'onVersionChanged';
+ }
+
+}
diff --git a/catalog-ui/app/scripts/utils/dictionary/dictionary.ts b/catalog-ui/app/scripts/utils/dictionary/dictionary.ts
new file mode 100644
index 0000000000..ef9a1bc4ea
--- /dev/null
+++ b/catalog-ui/app/scripts/utils/dictionary/dictionary.ts
@@ -0,0 +1,257 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+/**
+
+ This code was copy from collections.ts lib
+ https://github.com/basarat/typescript-collections
+**/
+
+module Sdc.Utils{
+ 'use strict';
+
+ // Used internally by dictionary
+ interface IDictionaryPair<K, V>{
+ key: K;
+ value: V;
+ }
+
+ export class Dictionary<K, V>{
+
+ /**
+ * Object holding the key-value pairs.
+ * @type {Object}
+ * @private
+ */
+ private table: { [key: string]: IDictionaryPair<K, V> };
+ //: [key: K] will not work since indices can only by strings in javascript and typescript enforces this.
+
+ /**
+ * Number of elements in the list.
+ * @type {number}
+ * @private
+ */
+ private nElements: number;
+
+ /**
+ * Function used to convert keys to strings.
+ * @type {function(Object):string}
+ * @private
+ */
+ private toStr: (key: K) => string;
+
+
+ /**
+ * Creates an empty dictionary.
+ * @class <p>Dictionaries map keys to values; each key can map to at most one value.
+ * This implementation accepts any kind of objects as keys.</p>
+ *
+ * <p>If the keys are custom objects a function which converts keys to unique
+ * strings must be provided. Example:</p>
+ * <pre>
+ * function petToString(pet) {
+ * return pet.name;
+ * }
+ * </pre>
+ * @constructor
+ * @param {function(Object):string=} toStrFunction optional function used
+ * to convert keys to strings. If the keys aren"t strings or if toString()
+ * is not appropriate, a custom function which receives a key and returns a
+ * unique string must be provided.
+ */
+ constructor(toStrFunction?: (key: K) => string) {
+ this.table = {};
+ this.nElements = 0;
+ this.toStr = toStrFunction || this.defaultToString;
+ }
+
+
+ /**
+ copy from angular.js isUndefined
+ */
+ private isUndefined = (value: any):boolean => {
+ return typeof value === 'undefined';
+ }
+
+ defaultToString = (item: any): string => {
+ return item.toString();
+ }
+
+ /**
+ * Returns the value to which this dictionary maps the specified key.
+ * Returns undefined if this dictionary contains no mapping for this key.
+ * @param {Object} key key whose associated value is to be returned.
+ * @return {*} the value to which this dictionary maps the specified key or
+ * undefined if the map contains no mapping for this key.
+ */
+ getValue = (key: K): V => {
+ let pair: IDictionaryPair<K, V> = this.table[this.toStr(key)];
+ if (this.isUndefined(pair)) {
+ return undefined;
+ }
+ return pair.value;
+ }
+
+
+ /**
+ * Associates the specified value with the specified key in this dictionary.
+ * If the dictionary previously contained a mapping for this key, the old
+ * value is replaced by the specified value.
+ * @param {Object} key key with which the specified value is to be
+ * associated.
+ * @param {Object} value value to be associated with the specified key.
+ * @return {*} previous value associated with the specified key, or undefined if
+ * there was no mapping for the key or if the key/value are undefined.
+ */
+ setValue = (key: K, value: V): V => {
+
+ if (this.isUndefined(key) || this.isUndefined(value)) {
+ return undefined;
+ }
+
+ let ret: V;
+ let k = this.toStr(key);
+ let previousElement: IDictionaryPair<K, V> = this.table[k];
+ if (this.isUndefined(previousElement)) {
+ this.nElements++;
+ ret = undefined;
+ } else {
+ ret = previousElement.value;
+ }
+ this.table[k] = {
+ key: key,
+ value: value
+ };
+ return ret;
+ }
+
+ /**
+ * Removes the mapping for this key from this dictionary if it is present.
+ * @param {Object} key key whose mapping is to be removed from the
+ * dictionary.
+ * @return {*} previous value associated with specified key, or undefined if
+ * there was no mapping for key.
+ */
+ remove = (key: K): V => {
+ let k = this.toStr(key);
+ let previousElement: IDictionaryPair<K, V> = this.table[k];
+ if (!this.isUndefined(previousElement)) {
+ delete this.table[k];
+ this.nElements--;
+ return previousElement.value;
+ }
+ return undefined;
+ }
+
+ /**
+ * Returns an array containing all of the keys in this dictionary.
+ * @return {Array} an array containing all of the keys in this dictionary.
+ */
+ keys = (): K[] => {
+ let array: K[] = [];
+ for (let name in this.table) {
+ if (this.table.hasOwnProperty(name)) {
+ let pair: IDictionaryPair<K, V> = this.table[name];
+ array.push(pair.key);
+ }
+ }
+ return array;
+ }
+
+ /**
+ * Returns an array containing all of the values in this dictionary.
+ * @return {Array} an array containing all of the values in this dictionary.
+ */
+ values = (): V[] => {
+ let array: V[] = [];
+ for (let name in this.table) {
+ if (this.table.hasOwnProperty(name)) {
+ let pair: IDictionaryPair<K, V> = this.table[name];
+ array.push(pair.value);
+ }
+ }
+ return array;
+ }
+
+ /**
+ * Executes the provided function once for each key-value pair
+ * present in this dictionary.
+ * @param {function(Object,Object):*} callback function to execute, it is
+ * invoked with two arguments: key and value. To break the iteration you can
+ * optionally return false.
+ */
+ forEach = (callback: (key: K, value: V) => any): void => {
+ for (let name in this.table) {
+ if (this.table.hasOwnProperty(name)) {
+ let pair: IDictionaryPair<K, V> = this.table[name];
+ let ret = callback(pair.key, pair.value);
+ if (ret === false) {
+ return;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns true if this dictionary contains a mapping for the specified key.
+ * @param {Object} key key whose presence in this dictionary is to be
+ * tested.
+ * @return {boolean} true if this dictionary contains a mapping for the
+ * specified key.
+ */
+ containsKey = (key: K): boolean => {
+ return !this.isUndefined(this.getValue(key));
+ }
+
+ /**
+ * Removes all mappings from this dictionary.
+ * @this {Dictionary}
+ */
+ clear = () => {
+
+ this.table = {};
+ this.nElements = 0;
+ }
+
+ /**
+ * Returns the number of keys in this dictionary.
+ * @return {number} the number of key-value mappings in this dictionary.
+ */
+ size = (): number => {
+ return this.nElements;
+ }
+
+ /**
+ * Returns true if this dictionary contains no mappings.
+ * @return {boolean} true if this dictionary contains no mappings.
+ */
+ isEmpty = (): boolean => {
+ return this.nElements <= 0;
+ }
+
+ toString = (): string => {
+ let toret = "{";
+ this.forEach((k, v) => {
+ toret = toret + "\n\t" + k.toString() + " : " + v.toString();
+ });
+ return toret + "\n}";
+ }
+ } // End of dictionary
+
+}
diff --git a/catalog-ui/app/scripts/utils/file-utils.ts b/catalog-ui/app/scripts/utils/file-utils.ts
new file mode 100644
index 0000000000..db6251f199
--- /dev/null
+++ b/catalog-ui/app/scripts/utils/file-utils.ts
@@ -0,0 +1,73 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+/// <reference path="../references"/>
+module Sdc.Utils {
+ export class FileUtils {
+
+ static '$inject' = [
+ '$window'
+ ];
+
+ constructor(private $window: any) {
+ }
+
+ public byteCharactersToBlob = (byteCharacters, contentType): any => {
+ contentType = contentType || '';
+ let sliceSize = 1024;
+ let bytesLength = byteCharacters.length;
+ let slicesCount = Math.ceil(bytesLength / sliceSize);
+ let byteArrays = new Array(slicesCount);
+
+ for (let sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
+ let begin = sliceIndex * sliceSize;
+ let end = Math.min(begin + sliceSize, bytesLength);
+
+ let bytes = new Array(end - begin);
+ for (let offset = begin, i = 0; offset < end; ++i, ++offset) {
+ bytes[i] = byteCharacters[offset].charCodeAt(0);
+ }
+ byteArrays[sliceIndex] = new Uint8Array(bytes);
+ }
+ return new Blob(byteArrays, {type: contentType});
+ };
+
+ public base64toBlob = (base64Data, contentType): any => {
+ let byteCharacters = atob(base64Data);
+ return this.byteCharactersToBlob(byteCharacters, contentType);
+ };
+
+ public downloadFile = (blob, fileName): void=> {
+ let url = this.$window.URL.createObjectURL(blob);
+ let downloadLink = document.createElement("a");
+
+ downloadLink.setAttribute('href', url);
+ downloadLink.setAttribute('download', fileName);
+ document.body.appendChild(downloadLink);
+ downloadLink.click();
+
+ //time out for firefox
+ setTimeout(()=> {
+ document.body.removeChild(downloadLink);
+ this.$window.URL.revokeObjectURL(url);
+ }, 100);
+ }
+
+ }
+}
diff --git a/catalog-ui/app/scripts/utils/functions.ts b/catalog-ui/app/scripts/utils/functions.ts
new file mode 100644
index 0000000000..32bc9243cf
--- /dev/null
+++ b/catalog-ui/app/scripts/utils/functions.ts
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+/// <reference path="../references"/>
+module Sdc.Utils.Functions {
+
+ export class QueueUtils {
+
+ private executionQueue : any;
+
+ constructor(private $q:ng.IQService){
+ this.executionQueue = this.getDummyPromise();
+ }
+
+
+ private getDummyPromise = (): ng.IPromise<boolean> => {
+ let deferred : ng.IDeferred<boolean>= this.$q.defer();
+ deferred.resolve(true);
+ return deferred.promise;
+ };
+
+
+ private addMethodToQueue = (runMe:Function) : void => {
+ this.executionQueue = this.executionQueue.then(runMe, runMe);
+ };
+
+ addNonBlockingUIAction = (update:Function , releaseUIcallBack:Function) : void => {
+ releaseUIcallBack();
+ this.addMethodToQueue(update);
+ };
+
+ // The Method call is responsible for releasing the UI
+ addBlockingUIAction = ( blockingServerRequest : Function ):void => {
+ this.addMethodToQueue(blockingServerRequest);
+ };
+
+ addBlockingUIActionWithReleaseCallback = ( blockingServerRequest : Function, releaseUIcallBack:Function):void=>{
+ this.addMethodToQueue(blockingServerRequest);
+ this.addMethodToQueue(releaseUIcallBack);
+ };
+ }
+}
diff --git a/catalog-ui/app/scripts/utils/menu-handler.ts b/catalog-ui/app/scripts/utils/menu-handler.ts
new file mode 100644
index 0000000000..0f2b7de3be
--- /dev/null
+++ b/catalog-ui/app/scripts/utils/menu-handler.ts
@@ -0,0 +1,145 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+/// <reference path="../references.ts"/>
+module Sdc.Utils {
+
+ 'use strict';
+
+ export class MenuItem {
+ text: string;
+ callback: (...args: Array<any>) => ng.IPromise<boolean>;
+ state: string;
+ action: string;
+ params: Array<any>;
+ isDisabled: boolean;
+ disabledRoles: Array<string>;
+ blockedForTypes:Array<string>; // This item will not be shown for specific components types.
+
+ //TODO check if needed
+ confirmationModal:string; // Open confirmation modal (user should select "OK" or "Cancel"), and continue with the action.
+ emailModal:string; // Open email modal (user should fill email details), and continue with the action.
+ url:string; // Data added to menu item, in case the function need to use it, example: for function "changeLifecycleState", I need to pass also the state "CHECKOUT" that I want the state to change to.
+
+
+ constructor(text: string, callback: (...args: Array<any>) => ng.IPromise<boolean>, state:string, action:string, params?: Array<any>, blockedForTypes?:Array<string>) {
+ this.text = text;
+ this.callback = callback;
+ this.state = state;
+ this.action = action;
+ this.params = params;
+ this.blockedForTypes = blockedForTypes;
+ }
+ }
+
+ export class MenuItemGroup {
+ selectedIndex: number;
+ menuItems: Array<MenuItem>;
+ itemClick: boolean;
+
+ constructor(selectedIndex?:number, menuItems?: Array<MenuItem>, itemClick?: boolean) {
+ this.selectedIndex = selectedIndex;
+ this.menuItems = menuItems;
+ this.itemClick = itemClick;
+ }
+
+ public updateSelectedMenuItemText (newText: string) {
+ this.menuItems[this.selectedIndex].text = newText;
+ }
+ }
+
+
+ export class MenuHandler {
+
+ static '$inject' = [
+ 'sdcConfig',
+ 'sdcMenu',
+ 'ComponentFactory',
+ '$templateCache',
+ '$filter',
+ '$modal',
+ 'ModalsHandler',
+ '$state',
+ '$q'
+ ];
+
+ constructor(
+ private sdcConfig:Models.IAppConfigurtaion,
+ private sdcMenu:Models.IAppMenu,
+ private ComponentFactory: ComponentFactory,
+ private $templateCache:ng.ITemplateCacheService,
+ private $filter:ng.IFilterService,
+ private $modal:ng.ui.bootstrap.IModalService,
+ private ModalsHandler: ModalsHandler,
+ private $state:ng.ui.IStateService,
+ private $q:ng.IQService
+ ) {
+
+ }
+
+
+ generateBreadcrumbsModelFromComponents = (components: Array<Sdc.Models.Components.Component>, selected:Sdc.Models.Components.Component):MenuItemGroup => {
+ let result = new MenuItemGroup(0, [], false);
+ if (components) {
+
+ // Search the component in all components by uuid (and not uniqueid, gives access to an assets's minor versions).
+ let selectedItem = _.find(components, (item:Sdc.Models.Components.Component) => {
+ return item.uuid === selected.uuid;
+ });
+
+ // If not found search by invariantUUID
+ if(undefined == selectedItem){
+ selectedItem = _.find(components, (item:Sdc.Models.Components.Component) => {
+ //invariantUUID && Certified State matches between major versions
+ return item.invariantUUID === selected.invariantUUID && item.lifecycleState === Utils.Constants.ComponentState.CERTIFIED;
+ });
+ }
+
+ // If not found search by name (name is unique).
+ if(undefined == selectedItem){
+ selectedItem = _.find(components, (item:Sdc.Models.Components.Component) => {
+ return item.name === selected.name;
+ });
+ }
+
+ result.selectedIndex = components.indexOf(selectedItem);
+ components[result.selectedIndex] = selected;
+ let clickItemCallback = (component: Sdc.Models.Components.Component): ng.IPromise<boolean> => {
+ this.$state.go('workspace.general', {id: component.uniqueId, type:component.componentType.toLowerCase(), mode: Utils.Constants.WorkspaceMode.VIEW});
+ return this.$q.when(true);
+ };
+
+ components.forEach((component:Sdc.Models.Components.Component) => {
+ let menuItem = new MenuItem(
+ // component.name,
+ component.getComponentSubType() + ': ' + this.$filter('resourceName')(component.name),
+ clickItemCallback,
+ null,
+ null,
+ [component]
+ );
+ // menuItem.text = component.name;
+ result.menuItems.push(menuItem);
+ });
+ }
+ return result;
+ };
+
+ }
+}
diff --git a/catalog-ui/app/scripts/utils/modals-handler.ts b/catalog-ui/app/scripts/utils/modals-handler.ts
new file mode 100644
index 0000000000..f3e80a7a24
--- /dev/null
+++ b/catalog-ui/app/scripts/utils/modals-handler.ts
@@ -0,0 +1,275 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+/**
+ * Created by obarda on 2/11/2016.
+ */
+/// <reference path="../references"/>
+module Sdc.Utils {
+
+ export interface IModalsHandler {
+
+ openViewerModal(component:Models.Components.Component):void;
+ openDistributionStatusModal(distribution: Models.Distribution,status:string):void;
+ openConfirmationModal (title:string, message:string, showComment:boolean, size?: string):ng.IPromise<any>;
+ openAlertModal (title:string, message:string, size?: string):ng.IPromise<any>;
+ openStandardModal (title:string, message:string, size?: string):ng.IPromise<any>;
+ openErrorModal (title:string, message:string, size?: string):ng.IPromise<any>;
+ openEmailModal(emailModel:ViewModels.IEmailModalModel) :ng.IPromise<any>;
+ openServerMessageModal(data:Sdc.ViewModels.IServerMessageModalModel): ng.IPromise<any>;
+ openClientMessageModal(data:Sdc.ViewModels.IClientMessageModalModel): ng.IPromise<ng.ui.bootstrap.IModalServiceInstance>;
+ openWizardArtifactModal(artifact: Models.ArtifactModel, component:Models.Components.Component): ng.IPromise<any>;
+ openWizard(componentType: Utils.Constants.ComponentType, component?:Models.Components.Component, importedFile?: any): ng.IPromise<any>;
+ }
+
+ export class ModalsHandler implements IModalsHandler{
+
+ static '$inject' = [
+ '$templateCache',
+ '$modal',
+ '$q'
+ ];
+
+ constructor(private $templateCache:ng.ITemplateCacheService,
+ private $modal:ng.ui.bootstrap.IModalService,
+ private $q:ng.IQService) {
+ }
+
+ openViewerModal = (component:Models.Components.Component):void => {
+
+ let modalOptions:ng.ui.bootstrap.IModalSettings = {
+ template: this.$templateCache.get('/app/scripts/view-models/component-viewer/component-viewer.html'),
+ controller: 'Sdc.ViewModels.ComponentViewerViewModel',
+ size: 'lg',
+ backdrop: 'static',
+ resolve: {
+ component: ():Models.Components.Component=> {
+ return component;
+ }
+ }
+ };
+ this.$modal.open(modalOptions);
+ };
+
+
+ openDistributionStatusModal = (distribution: Models.Distribution,status:string): ng.IPromise<any> => {
+ let deferred = this.$q.defer();
+ let modalOptions:ng.ui.bootstrap.IModalSettings = {
+ template: this.$templateCache.get('/app/scripts/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal-view.html'),
+ controller: 'Sdc.ViewModels.DistributionStatusModalViewModel',
+ size: 'sdc-xl',
+ backdrop: 'static',
+ resolve: {
+ data: ():any => {
+ return {
+ 'distribution': distribution,
+ 'status': status
+ };
+ }
+ }
+ };
+ let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$modal.open(modalOptions);
+ deferred.resolve(modalInstance.result);
+ return deferred.promise;
+ };
+
+
+
+ openAlertModal = (title:string, message:string, size?: string):ng.IPromise<any> => {
+ return this.openConfirmationModalBase(title, message, false, Utils.Constants.ModalType.ALERT, size);
+ };
+
+ openStandardModal = (title:string, message:string, size?: string):ng.IPromise<any> => {
+ return this.openConfirmationModalBase(title, message, false, Utils.Constants.ModalType.STANDARD, size);
+ };
+
+ openErrorModal = (title:string, message:string, size?: string):ng.IPromise<any> => {
+ return this.openConfirmationModalBase(title, message, false, Utils.Constants.ModalType.ERROR, size);
+ };
+
+ openConfirmationModal = (title:string, message:string, showComment:boolean, size?: string):ng.IPromise<any> => {
+ return this.openConfirmationModalBase(title, message, showComment, Utils.Constants.ModalType.STANDARD, size);
+ };
+
+ private openConfirmationModalBase = (title:string, message:string, showComment:boolean, type:Utils.Constants.ModalType, size?: string):ng.IPromise<any> => {
+ let deferred = this.$q.defer();
+ let modalOptions:ng.ui.bootstrap.IModalSettings = {
+ template: this.$templateCache.get('/app/scripts/view-models/modals/confirmation-modal/confirmation-modal-view.html'),
+ controller: 'Sdc.ViewModels.ConfirmationModalViewModel',
+ size: size? size:'sdc-sm',
+ backdrop: 'static',
+ resolve: {
+ confirmationModalModel: ():Sdc.ViewModels.IConfirmationModalModel => {
+ let model:Sdc.ViewModels.IConfirmationModalModel = {
+ title: title,
+ message: message,
+ showComment: showComment,
+ type: type
+ };
+ return model;
+ }
+ }
+ };
+
+ let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$modal.open(modalOptions);
+ deferred.resolve(modalInstance.result);
+ return deferred.promise;
+ };
+
+ openEmailModal = (emailModel:ViewModels.IEmailModalModel):ng.IPromise<any> => {
+
+ let deferred = this.$q.defer();
+ let modalOptions:ng.ui.bootstrap.IModalSettings = {
+ template: this.$templateCache.get('/app/scripts/view-models/modals/email-modal/email-modal-view.html'),
+ controller: 'Sdc.ViewModels.EmailModalViewModel',
+ size: 'sdc-sm',
+ backdrop: 'static',
+ resolve: {
+ emailModalModel: ():ViewModels.IEmailModalModel => {
+ return emailModel;
+ }
+ }
+ };
+ let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$modal.open(modalOptions);
+ deferred.resolve(modalInstance.result);
+ return deferred.promise;
+
+ };
+
+ openServerMessageModal = (data:Sdc.ViewModels.IServerMessageModalModel):ng.IPromise<any> => {
+ let deferred = this.$q.defer();
+ let modalOptions:ng.ui.bootstrap.IModalSettings = {
+ template: this.$templateCache.get('/app/scripts/view-models/modals/message-modal/message-server-modal/server-message-modal-view.html'),
+ controller: 'Sdc.ViewModels.ServerMessageModalViewModel',
+ size: 'sdc-sm',
+ backdrop: 'static',
+ resolve: {
+ serverMessageModalModel: ():Sdc.ViewModels.IServerMessageModalModel => {
+ return data;
+ }
+ }
+ };
+
+ let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$modal.open(modalOptions);
+ deferred.resolve(modalInstance.result);
+ return deferred.promise;
+ };
+
+ openClientMessageModal = (data:Sdc.ViewModels.IClientMessageModalModel):ng.IPromise<any> => {
+ let deferred = this.$q.defer();
+ let modalOptions:ng.ui.bootstrap.IModalSettings = {
+ template: this.$templateCache.get('/app/scripts/view-models/modals/message-modal/message-client-modal/client-message-modal-view.html'),
+ controller: 'Sdc.ViewModels.ClientMessageModalViewModel',
+ size: 'sdc-sm',
+ backdrop: 'static',
+ resolve: {
+ clientMessageModalModel: ():Sdc.ViewModels.IClientMessageModalModel => {
+ return data;
+ }
+ }
+ };
+ let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$modal.open(modalOptions);
+ deferred.resolve(modalInstance);
+ return deferred.promise;
+ };
+
+ openOnboadrdingModal = (okButtonText:string,currentCsarUUID?:string): ng.IPromise<any> => {
+ let deferred = this.$q.defer();
+ let modalOptions:ng.ui.bootstrap.IModalSettings = {
+ template: this.$templateCache.get('/app/scripts/view-models/modals/onboarding-modal/onboarding-modal-view.html'),
+ controller: 'Sdc.ViewModels.OnboardingModalViewModel',
+ size: 'sdc-xl',
+ backdrop: 'static',
+ resolve: {
+ okButtonText:():string=>{
+ return okButtonText;
+ },
+ currentCsarUUID:():string=>{
+ return currentCsarUUID||null;
+ }
+ }
+ };
+ let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$modal.open(modalOptions);
+ deferred.resolve(modalInstance.result);
+ return deferred.promise;
+ };
+
+
+ openWizard = (componentType: Utils.Constants.ComponentType, component?:Models.Components.Component, importedFile?: any): ng.IPromise<any> => {
+ let deferred = this.$q.defer();
+ let template = this.$templateCache.get('/app/scripts/view-models/wizard/wizard-creation-base.html');
+
+ let controller:string;
+ if(component){
+ controller = 'Sdc.ViewModels.Wizard.EditWizardViewModel'; //Edit mode
+ } else {
+ if (importedFile){
+ controller = 'Sdc.ViewModels.Wizard.ImportWizardViewModel'; // Import Mode
+ } else {
+ controller = 'Sdc.ViewModels.Wizard.CreateWizardViewModel'; // Create Mode
+ }
+ }
+ let modalOptions:ng.ui.bootstrap.IModalSettings = {
+ template: template,
+ controller: controller,
+ size: 'sdc-xl',
+ backdrop: 'static',
+ keyboard: false,
+ resolve: {
+ data: ():any => {
+ return {
+ 'componentType': componentType,
+ 'component': component,
+ 'importFile':importedFile
+ };
+ }
+ }
+ };
+
+ let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$modal.open(modalOptions);
+ deferred.resolve(modalInstance.result);
+ return deferred.promise;
+ };
+
+ openWizardArtifactModal = (artifact: Models.ArtifactModel, component:Models.Components.Component): ng.IPromise<any> => {
+ let deferred = this.$q.defer();
+ let viewModelsHtmlBasePath:string = '/app/scripts/view-models/';
+ let modalOptions:ng.ui.bootstrap.IModalSettings = {
+ template: this.$templateCache.get(viewModelsHtmlBasePath + 'wizard/artifact-form-step/artifact-form-step-view.html'),
+ controller: 'Sdc.ViewModels.Wizard.ArtifactResourceFormStepViewModel',
+ size: 'sdc-md',
+ backdrop: 'static',
+ keyboard: false,
+ resolve: {
+ artifact: ():Models.ArtifactModel => {
+ return artifact;
+ },
+ component: (): Models.Components.Component => {
+ return component;
+ }
+ }
+ };
+
+ let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$modal.open(modalOptions);
+ deferred.resolve(modalInstance.result);
+ return deferred.promise;
+ };
+
+ }
+}
diff --git a/catalog-ui/app/scripts/utils/prototypes.ts b/catalog-ui/app/scripts/utils/prototypes.ts
new file mode 100644
index 0000000000..de961cfc4b
--- /dev/null
+++ b/catalog-ui/app/scripts/utils/prototypes.ts
@@ -0,0 +1,155 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+interface String {
+ format(variables:Array<string>):string
+}
+
+interface Array<T> {
+ clean(o: T): Array<T>;
+}
+
+
+/**
+ * This function will replace the %<number> with strings (from array).
+ * Example: "Requested '%1' resource was not found.".format(["MyResource"]);
+ * Note: in case the array contains empty string the function will also remove the '' or the "".
+ */
+if (!String.hasOwnProperty("format")) {
+ String.prototype["format"] = function (variables:Array<string>) : string {
+
+ if (variables===null || variables===undefined || variables.length===0){
+ variables=[''];
+ }
+
+ for (let i=0;i<variables.length;i++){
+ if (variables[i]==='' || variables[i]===null){
+ variables[i]='--DELETE--';
+ }
+ }
+
+ let res = this.replace(/%(\d+)/g, function(_,m) {
+ return variables[--m];
+ });
+
+ res = res.replace(" '--DELETE--' "," ");
+ res = res.replace(" \"--DELETE--\" "," ");
+ res = res.replace("'--DELETE--'","");
+ res = res.replace("\"--DELETE--\"","");
+ res = res.replace("--DELETE--","");
+
+ return res;
+ };
+}
+
+if (!String.hasOwnProperty("capitalizeFirstLetter")) {
+ String.prototype["capitalizeFirstLetter"] = function() {
+ return this.charAt(0).toUpperCase() + this.slice(1);
+ };
+}
+
+if (!String.hasOwnProperty("replaceAll")) {
+ String.prototype["replaceAll"] = function (find:string, replace:string) : string {
+ return this.replace(new RegExp(find, 'g'), replace);
+ };
+}
+
+if (!Array.hasOwnProperty("clean")) {
+ Array.prototype.clean = function (deleteValue) {
+ for (let i = 0; i < this.length; i++) {
+ if (this[i] == deleteValue) {
+ this.splice(i, 1);
+ i--;
+ }
+ }
+ return this;
+ };
+}
+
+if (!Array.prototype.map) {
+ Array.prototype.map = function(callback, thisArg) {
+
+ let T, A, k;
+
+ if (this == null) {
+ throw new TypeError(" this is null or not defined");
+ }
+
+ // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
+ let O = Object(this);
+
+ // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
+ // 3. Let len be ToUint32(lenValue).
+ let len = O.length >>> 0;
+
+ // 4. If IsCallable(callback) is false, throw a TypeError exception.
+ // See: http://es5.github.com/#x9.11
+ if (typeof callback !== "function") {
+ throw new TypeError(callback + " is not a function");
+ }
+
+ // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
+ if (thisArg) {
+ T = thisArg;
+ }
+
+ // 6. Let A be a new array created as if by the expression new Array(len) where Array is
+ // the standard built-in constructor with that name and len is the value of len.
+ A = new Array(len);
+
+ // 7. Let k be 0
+ k = 0;
+
+ // 8. Repeat, while k < len
+ while(k < len) {
+
+ let kValue, mappedValue;
+
+ // a. Let Pk be ToString(k).
+ // This is implicit for LHS operands of the in operator
+ // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
+ // This step can be combined with c
+ // c. If kPresent is true, then
+ if (k in O) {
+
+ // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
+ kValue = O[ k ];
+
+ // ii. Let mappedValue be the result of calling the Call internal method of callback
+ // with T as the this value and argument list containing kValue, k, and O.
+ mappedValue = callback.call(T, kValue, k, O);
+
+ // iii. Call the DefineOwnProperty internal method of A with arguments
+ // Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true},
+ // and false.
+
+ // In browsers that support Object.defineProperty, use the following:
+ // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });
+
+ // For best browser support, use the following:
+ A[ k ] = mappedValue;
+ }
+ // d. Increase k by 1.
+ k++;
+ }
+
+ // 9. return A
+ return A;
+ };
+}
diff --git a/catalog-ui/app/scripts/utils/validation-utils.ts b/catalog-ui/app/scripts/utils/validation-utils.ts
new file mode 100644
index 0000000000..7618e7d0e3
--- /dev/null
+++ b/catalog-ui/app/scripts/utils/validation-utils.ts
@@ -0,0 +1,173 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+/// <reference path="../references"/>
+
+module Sdc.Utils {
+ class basePattern{
+ pattern:RegExp;
+ base:number;
+ constructor(pattern:RegExp, base:number){
+ this.pattern = pattern;
+ this.base = base;
+ }
+ }
+
+ export interface IMapRegex{
+ integer: RegExp;
+ boolean: RegExp;
+ float: RegExp;
+ string: RegExp;
+ }
+
+ export class ValidationUtils {
+
+ static '$inject' = [
+ 'IntegerNoLeadingZeroValidationPattern',
+ 'FloatValidationPattern',
+ 'CommentValidationPattern',
+ 'BooleanValidationPattern',
+ 'NumberValidationPattern',
+ 'LabelValidationPattern',
+ ];
+ private trueRegex : string = '[t][r][u][e]|[t]|[o][n]|[y]|[y][e][s]|[1]';
+ private falseRegex : string = '[f][a][l][s][e]|[f]|[o][f][f]|[n]|[n][o]|[0]';
+ private heatBooleanValidationPattern : RegExp = new RegExp( '^('+this.trueRegex+'|'+this.falseRegex+')$');
+
+
+ constructor(private IntegerNoLeadingZeroValidationPattern:RegExp,
+ private FloatValidationPattern:RegExp,
+ private CommentValidationPattern:RegExp,
+ private BooleanValidationPattern:RegExp,
+ private NumberValidationPattern:RegExp,
+ private LabelValidationPattern:RegExp) {}
+
+ public stripAndSanitize(text:string):string{
+ if(!text){
+ return null;
+ }
+ return text.replace(/\s+/g, ' ').replace(/%[A-Fa-f0-9]{2}/g, '').trim();
+ }
+
+ public getValidationPattern = (validationType:string , parameterType?:string) : RegExp => {
+ switch (validationType){
+ case 'integer':
+ return this.IntegerNoLeadingZeroValidationPattern;
+ case 'float':
+ return this.FloatValidationPattern;
+ case 'number':
+ return this.NumberValidationPattern;
+ case 'string':
+ return this.CommentValidationPattern;
+ case 'boolean':
+ {
+ //Bug Fix DE197437 [Patch]Mismatch between BE to FE regarding supported characters in Boolean filed
+ if( parameterType && parameterType === 'heat'){
+ return this.heatBooleanValidationPattern;
+ }
+ else{
+ return this.BooleanValidationPattern;
+ }
+
+ }
+
+ case 'label':
+ return this.LabelValidationPattern;
+ case 'category':
+ return this.LabelValidationPattern;
+ default :
+ return null;
+ }
+ };
+
+ public getPropertyListPatterns():IMapRegex {
+ return {
+ integer: /^(0|[-+]?[1-9][0-9]*|[-+]?0x[0-9a-fA-F]+|[-+]?0o[0-7]+)(,?(0|[-+]?[1-9][0-9]*|[-+]?0x[0-9a-fA-F]+|[-+]?0o[0-7]+))*$/,
+ string: /^"[\u0000-\u0021\u0023-\u00BF]+"(\s*,?\s*"[\u0000-\u0021\u0023-\u00BF]+")*$/,
+ boolean: /^([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee])(,?([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]))*$/,
+ float: /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?(,?[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?)*$/
+ };
+ }
+ public getPropertyMapPatterns():IMapRegex {
+ return {
+ integer: /^"\w+"\s*:\s?(0|[-+]?[1-9][0-9]*|[-+]?0x[0-9a-fA-F]+|[-+]?0o[0-7]+)+(\s*,?\s*"\w+"\s?:\s?(0|[-+]?[1-9][0-9]*|[-+]?0x[0-9a-fA-F]+|[-+]?0o[0-7]+)+)*$/,
+ string: /^"\w+"\s?:\s?"[\u0000-\u0021\u0023-\u00BF]*"(\s*,?\s*"\w+"\s?:\s?"[\u0000-\u0021\u0023-\u00BF]*")*$/,
+ boolean: /^"\w+"\s?:\s?([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee])(\s*,?\s*"\w+"\s?:\s?([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]))*$/,
+ float: /^"\w+"\s?:\s?[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?(\s*,?\s*"\w+"\s?:\s?[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?)*$/
+ };
+ }
+ public validateUniqueKeys(viewValue:string):boolean {
+ if(!viewValue) {
+ return true; //allow empty value
+ }
+
+ let json:string = "{" + viewValue.replace(/\s\s+/g, ' ') + "}";
+ try{
+ let obj:any = JSON.parse(json);
+ /*
+ //Method #1 : check json string length before & after parsing
+ let newJson:string = JSON.stringify(obj);
+ if (newJson.length < json.length) {
+ return false;
+ }*/
+
+ //Method #2 : check how many times we can find "KEY": in json string
+ let result:boolean = true;
+ Object.keys(obj).forEach((key:string) => {
+ result = result && json.split('"' + key + '":').length === 2;
+ });
+ return result;
+
+ }catch(e){
+ return false; //not a valid JSON
+ }
+
+ //return true;
+ }
+
+ public validateJson = (json:string):boolean => {
+ try{
+ JSON.parse(json);
+ return true;
+ }catch(err){
+ console.log('invalid json');
+ return false;
+ }
+ };
+
+ public validateIntRange = (value:string):boolean => {
+
+ let base8 = new basePattern(/^([-+]?0o[0-7]+)$/, 8);
+ let base10 = new basePattern(/^(0|[-+]?[1-9][0-9]*)$/, 10);
+ let base16 = new basePattern(/^([-+]?0x[0-9a-fA-F]+)$/, 16);
+
+ let min:number = -0x80000000;
+ let max:number = 0x7fffffff;
+ let intPatterns:Array<basePattern> = [base8, base10, base16];
+ let matchedBase = _.find(intPatterns, (item)=> {
+ return item.pattern.test(value);
+ });
+
+ let parsed:number = parseInt(value.replace('o',''), matchedBase.base);
+ if(parsed){
+ return min <= parsed && max >= parsed;
+ }
+ }
+ }
+}