- + + [fePropertiesMap]="instanceFePropertiesMap" + [readonly]="isReadonly" + [inputs]="inputs | searchFilter:'name':searchQuery" + [instanceNamesMap]="componentInstanceNamesMap" + [isLoading]="loadingInputs" + (deleteInput)="deleteInput($event)" + (inputChanged)="dataChanged($event)"> diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.less b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.less index 855bdc5bcb..a1309aba61 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.less +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.less @@ -133,13 +133,12 @@ flex-direction:column; margin: 0px 0 0 1em; overflow-x:auto; - .add-btn{ + .add-btn{ align-self: flex-end; margin-top: 10px; margin-bottom: 19px; } - /deep/ .tabs { border-bottom: solid 1px #d0d0d0; } diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts index 061439800f..4b84f0e66f 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts @@ -19,58 +19,34 @@ */ import * as _ from "lodash"; -import {Component, ViewChild, Inject, TemplateRef} from "@angular/core"; +import { Component, ViewChild, Inject, TemplateRef } from "@angular/core"; import { PropertiesService } from "../../services/properties.service"; -import { - PropertyFEModel, - InstanceFePropertiesMap, - InstanceBePropertiesMap, - InstancePropertiesAPIMap, - Component as ComponentData, - FilterPropertiesAssignmentData, - ModalModel, - ButtonModel, - Capability, - ToscaPresentationData -} from "app/models"; +import { PropertyFEModel, InstanceFePropertiesMap, InstanceBePropertiesMap, InstancePropertiesAPIMap, Component as ComponentData, FilterPropertiesAssignmentData, ModalModel, ButtonModel } from "app/models"; import { ResourceType } from "app/utils"; -import {ComponentServiceNg2} from "../../services/component-services/component.service"; -import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service" -import { - InputBEModel, - InputFEModel, - ComponentInstance, - GroupInstance, - PolicyInstance, - PropertyBEModel, - DerivedFEProperty, - SimpleFlatProperty, - CapabilitiesGroup -} from "app/models"; +import { ComponentServiceNg2 } from "../../services/component-services/component.service"; +import { TopologyTemplateService } from "../../services/component-services/topology-template.service"; +import { ComponentInstanceServiceNg2 } from "../../services/component-instance-services/component-instance.service" +import { InputBEModel, InputFEModel, ComponentInstance, GroupInstance, PolicyInstance, PropertyBEModel, DerivedFEProperty, SimpleFlatProperty } from "app/models"; import { KeysPipe } from 'app/ng2/pipes/keys.pipe'; -import {WorkspaceMode, EVENTS} from "../../../utils/constants"; -import {EventListenerService} from "app/services/event-listener-service" -import {HierarchyDisplayOptions} from "../../components/logic/hierarchy-navigtion/hierarchy-display-options"; -import {FilterPropertiesAssignmentComponent} from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component"; -import {PropertyRowSelectedEvent} from "../../components/logic/properties-table/properties-table.component"; -import {HierarchyNavService} from "./services/hierarchy-nav.service"; -import {PropertiesUtils} from "./services/properties.utils"; -import {ComponentModeService} from "../../services/component-services/component-mode.service"; -import {ModalService} from "../../services/modal.service"; -import {Tabs, Tab} from "../../components/ui/tabs/tabs.component"; -import {InputsUtils} from "./services/inputs.utils"; -import {PropertyCreatorComponent} from "./property-creator/property-creator.component"; -import {DeclareListComponent} from "./declare-list/declare-list.component"; +import { WorkspaceMode, EVENTS, PROPERTY_TYPES } from "../../../utils/constants"; +import { EventListenerService } from "app/services/event-listener-service" +import { HierarchyDisplayOptions } from "../../components/logic/hierarchy-navigtion/hierarchy-display-options"; +import { FilterPropertiesAssignmentComponent } from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component"; +import { PropertyRowSelectedEvent } from "../../components/logic/properties-table/properties-table.component"; +import { HierarchyNavService } from "./services/hierarchy-nav.service"; +import { PropertiesUtils } from "./services/properties.utils"; +import { ComponentModeService } from "../../services/component-services/component-mode.service"; +import { Tabs, Tab } from "../../components/ui/tabs/tabs.component"; +import { InputsUtils } from "./services/inputs.utils"; import { InstanceFeDetails } from "../../../models/instance-fe-details"; -import { SdcUiComponents } from "sdc-ui/lib/angular"; -//import { ModalService as ModalServiceSdcUI} from "sdc-ui/lib/angular/modals/modal.service"; -import { IModalButtonComponent } from "sdc-ui/lib/angular/modals/models/modal-config"; +import { SdcUiServices, SdcUiCommon } from "onap-ui-angular"; import { UnsavedChangesComponent } from "app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component"; -import {Observable} from "rxjs"; -import { DataTypeService } from "app/ng2/services/data-type.service"; -import { DataTypeModel } from "app/models"; -import { PROPERTY_DATA, PROPERTY_TYPES } from "app/utils"; -import { PropertyDeclareAPIModel} from "app/models"; +import {PropertyCreatorComponent} from "./property-creator/property-creator.component"; +import {ModalService} from "../../services/modal.service"; +import { DeclareListComponent } from "./declare-list/declare-list.component"; +import { CapabilitiesGroup, Capability } from "../../../models/capability"; +import { ToscaPresentationData } from "../../../models/tosca-presentation"; +import { Observable } from "rxjs"; const SERVICE_SELF_TITLE = "SELF"; @Component({ @@ -119,7 +95,7 @@ export class PropertiesAssignmentComponent { stateChangeStartUnregister:Function; serviceBePropertiesMap: InstanceBePropertiesMap; serviceBeCapabilitiesPropertiesMap: InstanceBePropertiesMap; - selectedInstance_FlattenCapabilitiesList: Array; + selectedInstance_FlattenCapabilitiesList: Capability[]; @ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs; @ViewChild('propertyInputTabs') propertyInputTabs: Tabs; @@ -136,12 +112,13 @@ export class PropertiesAssignmentComponent { @Inject("$state") private $state:ng.ui.IStateService, @Inject("Notification") private Notification:any, private componentModeService:ComponentModeService, - private ModalService:ModalService, private EventListenerService:EventListenerService, - private ModalServiceSdcUI: SdcUiComponents.ModalService) { + private ModalServiceSdcUI: SdcUiServices.ModalService, + private ModalService: ModalService, + private keysPipe:KeysPipe, + private topologyTemplateService: TopologyTemplateService) { this.instanceFePropertiesMap = new InstanceFePropertiesMap(); - /* This is the way you can access the component data, please do not use any data except metadata, all other data should be received from the new api calls on the first time than if the data is already exist, no need to call the api again - Ask orit if you have any questions*/ this.component = _stateParams.component; @@ -159,8 +136,8 @@ export class PropertiesAssignmentComponent { this.loadingPolicies = true; this.loadingInstances = true; this.loadingProperties = true; - this.componentServiceNg2 - .getComponentInputsWithProperties(this.component) + this.topologyTemplateService + .getComponentInputsWithProperties(this.component.componentType, this.component.uniqueId) .subscribe(response => { _.forEach(response.inputs, (input: InputBEModel) => { const newInput: InputFEModel = new InputFEModel(input); @@ -169,7 +146,7 @@ export class PropertiesAssignmentComponent { }); this.loadingInputs = false; - }); + }, error => {}); //ignore error this.componentServiceNg2 .getComponentResourcePropertiesData(this.component) .subscribe(response => { @@ -177,6 +154,7 @@ export class PropertiesAssignmentComponent { this.instances = []; this.instances.push(...response.componentInstances); this.instances.push(...response.groupInstances); + this.instances.push(...response.policies); _.forEach(response.policies, (policy: any) => { const newPolicy: InputFEModel = new InputFEModel(policy); @@ -199,7 +177,7 @@ export class PropertiesAssignmentComponent { this.loadingProperties = false; } this.selectFirstInstanceByDefault(); - }); + }, error => { this.loadingInstances = false; }); //ignore error this.stateChangeStartUnregister = this.$scope.$on('$stateChangeStart', (event, toState, toParams) => { // stop if has changed properties @@ -238,14 +216,14 @@ export class PropertiesAssignmentComponent { getServiceProperties(){ this.loadingProperties = false; - this.componentServiceNg2 - .getServiceProperties(this.component) - .subscribe(response => { + this.topologyTemplateService + .getServiceProperties(this.component.uniqueId) + .subscribe((response) => { this.serviceBePropertiesMap = new InstanceBePropertiesMap(); this.serviceBePropertiesMap[this.component.uniqueId] = response; this.processInstancePropertiesResponse(this.serviceBePropertiesMap, false); this.loadingProperties = false; - }, error => { + }, (error) => { this.loadingProperties = false; }); } @@ -267,14 +245,12 @@ export class PropertiesAssignmentComponent { this.loadingProperties = true; if (instance instanceof ComponentInstance) { let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap(); - this.selectedInstance_FlattenCapabilitiesList = instance.capabilities ? CapabilitiesGroup.getFlattenedCapabilities(instance.capabilities) : []; if (this.isInput(instance.originType)) { this.componentInstanceServiceNg2 .getComponentInstanceInputs(this.component, instance) .subscribe(response => { instanceBePropertiesMap[instance.uniqueId] = response; this.processInstancePropertiesResponse(instanceBePropertiesMap, true); - this.processInstanceCapabilitiesPropertiesResponse(false); this.loadingProperties = false; }, error => { }); //ignore error @@ -286,7 +262,6 @@ export class PropertiesAssignmentComponent { .subscribe(response => { instanceBePropertiesMap[instance.uniqueId] = response; this.processInstancePropertiesResponse(instanceBePropertiesMap, false); - this.processInstanceCapabilitiesPropertiesResponse(false); this.loadingProperties = false; }, error => { }); //ignore error @@ -305,7 +280,7 @@ export class PropertiesAssignmentComponent { } else if (instance instanceof PolicyInstance) { let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap(); this.componentInstanceServiceNg2 - .getComponentPolicyInstanceProperties(this.component, this.selectedInstanceData.uniqueId) + .getComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId) .subscribe((response) => { instanceBePropertiesMap[instance.uniqueId] = response; this.processInstancePropertiesResponse(instanceBePropertiesMap, false); @@ -480,7 +455,7 @@ export class PropertiesAssignmentComponent { let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap(); let selectedPolicyInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap(); let selectedComponentInstancesInputs: InstanceBePropertiesMap = new InstanceBePropertiesMap(); - let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []); + let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []); angular.forEach(instancesIds, (instanceId: string): void => { let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId); @@ -500,7 +475,7 @@ export class PropertiesAssignmentComponent { let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties); - //move changed capabilities properties from componentInstanceInputsMap obj to componentInstanceProperties + //move changed capabilities properties from componentInstanceInputsMap obj to componentInstanceProperties inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] = (inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] || []).concat( _.filter( @@ -526,15 +501,14 @@ export class PropertiesAssignmentComponent { } } ); - - this.componentServiceNg2 + this.topologyTemplateService .createInput(this.component, inputsToCreate, this.isSelf()) - .subscribe(response => { + .subscribe((response) => { this.setInputTabIndication(response.length); this.checkedPropertiesCount = 0; this.checkedChildPropertiesCount = 0; _.forEach(response, (input: InputBEModel) => { - let newInput: InputFEModel = new InputFEModel(input); + const newInput: InputFEModel = new InputFEModel(input); this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue); this.inputs.push(newInput); this.updatePropertyValueAfterDeclare(newInput); @@ -628,8 +602,8 @@ export class PropertiesAssignmentComponent { }; console.log("save button clicked. input=", input); - this.componentServiceNg2 - .createListInput(this.component, input, this.isSelf()) + this.topologyTemplateService + .createListInput(this.component.uniqueId, input, this.isSelf()) .subscribe(response => { this.setInputTabIndication(response.length); this.checkedPropertiesCount = 0; @@ -662,8 +636,8 @@ export class PropertiesAssignmentComponent { console.log('declareListProperties() - leave'); }; - /*** DECLARE PROPERTIES/POLICIES ***/ - declarePropertiesToPolicies = (): void => { + /*** DECLARE PROPERTIES/POLICIES ***/ + declarePropertiesToPolicies = (): void => { let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap(); let instancesIds = new KeysPipe().transform(this.instanceFePropertiesMap, []); @@ -679,7 +653,7 @@ export class PropertiesAssignmentComponent { let policiesToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(null, selectedComponentInstancesProperties, null, null); this.loadingPolicies = true; - this.componentServiceNg2 + this.topologyTemplateService .createPolicy(this.component, policiesToCreate, this.isSelf()) .subscribe(response => { this.setPolicyTabIndication(response.length); @@ -688,7 +662,7 @@ export class PropertiesAssignmentComponent { this.loadingPolicies = false; }); //ignore error - }; + } displayPoliciesAsDeclared = (policies) => { _.forEach(policies, (policy: any) => { @@ -699,8 +673,7 @@ export class PropertiesAssignmentComponent { this.updatePropertyValueAfterDeclare(newPolicy); this.policies.push(policy); }); - }; - + } saveChangedData = ():Promise<(PropertyBEModel|InputBEModel)[]> => { return new Promise((resolve, reject) => { @@ -736,7 +709,8 @@ export class PropertiesAssignmentComponent { if (changedInputsProperties.length && changedCapabilitiesProperties.length) { request = Observable.forkJoin( this.componentInstanceServiceNg2.updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties), - this.componentInstanceServiceNg2.updateInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties) + this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId, + this.selectedInstanceData.uniqueId, changedCapabilitiesProperties) ); } else if (changedInputsProperties.length) { @@ -745,7 +719,7 @@ export class PropertiesAssignmentComponent { } else if (changedCapabilitiesProperties.length) { request = this.componentInstanceServiceNg2 - .updateInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties); + .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties); } handleSuccess = (response) => { // reset each changed property with new value and remove it from changed properties list @@ -757,19 +731,18 @@ export class PropertiesAssignmentComponent { }; } else { if (this.isSelf()) { - request = this.componentServiceNg2.updateServiceProperties(this.component, _.map(changedProperties, cp => { + request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId, _.map(changedProperties, cp => { delete cp.constraints; return cp; })); } else { request = this.componentInstanceServiceNg2 - .updateInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedProperties); + .updateInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties); } handleSuccess = (response) => { // reset each changed property with new value and remove it from changed properties list response.forEach((resProp) => { - const changedProp = _.find(this.changedData, changedDataObject => changedDataObject.uniqueId === resProp.uniqueId); - this.changedData = _.filter(this.changedData, changedDataObject => changedDataObject.uniqueId !== resProp.uniqueId); + const changedProp = this.changedData.shift(); this.propertiesUtils.resetPropertyValue(changedProp, resProp.value); }); resolve(response); @@ -778,7 +751,7 @@ export class PropertiesAssignmentComponent { } } else if (this.selectedInstanceData instanceof GroupInstance) { request = this.componentInstanceServiceNg2 - .updateComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedProperties); + .updateComponentGroupInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties); handleSuccess = (response) => { // reset each changed property with new value and remove it from changed properties list response.forEach((resProp) => { @@ -790,7 +763,7 @@ export class PropertiesAssignmentComponent { }; } else if (this.selectedInstanceData instanceof PolicyInstance) { request = this.componentInstanceServiceNg2 - .updateComponentPolicyInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedProperties); + .updateComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId, changedProperties); handleSuccess = (response) => { // reset each changed property with new value and remove it from changed properties list response.forEach((resProp) => { @@ -802,6 +775,7 @@ export class PropertiesAssignmentComponent { }; } } else if (this.isInputsTabSelected) { + const changedInputs: InputBEModel[] = this.changedData.map((changedInput) => { changedInput = changedInput; const inputBE = new InputBEModel(changedInput); @@ -925,27 +899,27 @@ export class PropertiesAssignmentComponent { { title: modalTitle, size: 'sm', - type: 'custom', - testId: "id", - + type: SdcUiCommon.ModalType.custom, + testId: "navigate-modal", + buttons: [ - {id: 'cancelButton', text: 'Cancel', type: 'secondary', size: 'xsm', closeModal: true, callback: () => reject()}, - {id: 'discardButton', text: 'Discard', type: 'secondary', size: 'xsm', closeModal: true, callback: () => { this.reverseChangedData(); resolve()}}, - {id: 'saveButton', text: 'Save', type: 'primary', size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)} - ] as IModalButtonComponent[] - }, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData}); + {id: 'cancelButton', text: 'Cancel', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => reject()}, + {id: 'discardButton', text: 'Discard', type: SdcUiCommon.ButtonType.secondary, size: 'xsm', closeModal: true, callback: () => { this.reverseChangedData(); resolve()}}, + {id: 'saveButton', text: 'Save', type: SdcUiCommon.ButtonType.primary, size: 'xsm', closeModal: true, disabled: !this.isValidChangedData, callback: () => this.doSaveChangedData(resolve, reject)} + ] as SdcUiCommon.IModalButtonComponent[] + } as SdcUiCommon.IModalConfig, UnsavedChangesComponent, {isValidChangedData: this.isValidChangedData}); }); } updatePropertyValueAfterDeclare = (input: InputFEModel) => { if (this.instanceFePropertiesMap[input.instanceUniqueId]) { - let instanceName = input.instanceUniqueId.slice(input.instanceUniqueId.lastIndexOf('.') + 1); - let propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => { - return feProperty.uniqueId === input.propertyId && + const instanceName = input.instanceUniqueId.slice(input.instanceUniqueId.lastIndexOf('.') + 1); + const propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => { + return feProperty.name == input.relatedPropertyName && (feProperty.name == input.relatedPropertyName || input.name === instanceName.concat('_').concat(feProperty.name.replace(/[.]/g, '_'))); }); - let inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined; + const inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined; propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value this.propertiesService.disableRelatedProperties(propertyForUpdatindVal, inputPath); this.propertiesUtils.resetPropertyValue(propertyForUpdatindVal, input.relatedPropertyValue, inputPath); @@ -968,7 +942,7 @@ export class PropertiesAssignmentComponent { setPolicyTabIndication = (numPolicies: number): void => { this.propertyInputTabs.setTabIndication('Policies', numPolicies); - }; + } resetUnsavedChangesForInput = (input:InputFEModel) => { this.inputsUtils.resetInputDefaultValue(input, input.defaultValue); @@ -1009,9 +983,9 @@ export class PropertiesAssignmentComponent { deletePolicy = (policy: PolicyInstance) => { this.loadingPolicies = true; - this.componentServiceNg2 + this.topologyTemplateService .deletePolicy(this.component, policy) - .subscribe(response => { + .subscribe((response) => { this.policies = this.policies.filter(policy => policy.uniqueId !== response.uniqueId); //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead! this.changeSelectedInstance(this.selectedInstanceData); @@ -1020,25 +994,25 @@ export class PropertiesAssignmentComponent { }; deleteProperty = (property: PropertyFEModel) => { - let propertyToDelete = new PropertyFEModel(property); + const propertyToDelete = new PropertyFEModel(property); this.loadingProperties = true; - let feMap = this.instanceFePropertiesMap; - this.componentServiceNg2 - .deleteServiceProperty(this.component, propertyToDelete) - .subscribe(response => { + const feMap = this.instanceFePropertiesMap; + this.topologyTemplateService + .deleteServiceProperty(this.component.uniqueId, propertyToDelete) + .subscribe((response) => { const props = feMap[this.component.uniqueId]; props.splice(props.findIndex(p => p.uniqueId === response),1); this.loadingProperties = false; - }, error => { + }, (error) => { this.loadingProperties = false; console.error(error); }); - }; + } /*** addProperty ***/ addProperty = () => { let modalTitle = 'Add Property'; - const modal = this.ModalService.createCustomModal(new ModalModel( + let modal = this.ModalService.createCustomModal(new ModalModel( 'sm', modalTitle, null, @@ -1046,10 +1020,10 @@ export class PropertiesAssignmentComponent { new ButtonModel('Save', 'blue', () => { modal.instance.dynamicContent.instance.isLoading = true; const newProperty: PropertyBEModel = modal.instance.dynamicContent.instance.propertyModel; - this.componentServiceNg2.createServiceProperty(this.component, newProperty) - .subscribe(response => { + this.topologyTemplateService.createServiceProperty(this.component.uniqueId, newProperty) + .subscribe((response) => { modal.instance.dynamicContent.instance.isLoading = false; - let newProp: PropertyFEModel = this.propertiesUtils.convertAddPropertyBAToPropertyFE(response); + const newProp: PropertyFEModel = this.propertiesUtils.convertAddPropertyBAToPropertyFE(response); this.instanceFePropertiesMap[this.component.uniqueId].push(newProp); modal.instance.close(); }, (error) => { @@ -1059,7 +1033,6 @@ export class PropertiesAssignmentComponent { title: 'Failure' }); }); - }, () => !modal.instance.dynamicContent.instance.checkFormValidForSubmit()), new ButtonModel('Cancel', 'outline grey', () => { modal.instance.close(); @@ -1069,24 +1042,23 @@ export class PropertiesAssignmentComponent { )); this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {}); modal.instance.open(); - }; + } /*** SEARCH RELATED FUNCTIONS ***/ searchPropertiesInstances = (filterData:FilterPropertiesAssignmentData) => { let instanceBePropertiesMap:InstanceBePropertiesMap; this.componentServiceNg2 .filterComponentInstanceProperties(this.component, filterData) - .subscribe(response => { - + .subscribe((response) => { this.processInstancePropertiesResponse(response, false); this.hierarchyPropertiesDisplayOptions.searchText = filterData.propertyName;//mark results in tree this.searchPropertyName = filterData.propertyName;//mark in table this.hierarchyNavTabs.triggerTabChange('Composition'); this.propertiesNavigationData = []; this.displayClearSearch = true; - }, error => {}); //ignore error + }, (error) => {}); //ignore error - }; + } clearSearch = () => { this.instancesNavigationData = this.instances; @@ -1106,5 +1078,6 @@ export class PropertiesAssignmentComponent { private isInput = (instanceType:string):boolean =>{ return instanceType === ResourceType.VF || instanceType === ResourceType.PNF || instanceType === ResourceType.CVFC || instanceType === ResourceType.CR; } + } diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/property-creator/property-creator.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/property-creator/property-creator.component.ts index 7d76904539..5053d52cc8 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/property-creator/property-creator.component.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/property-creator/property-creator.component.ts @@ -1,79 +1,78 @@ -import * as _ from "lodash"; -import {Component} from '@angular/core'; -import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component"; -import { DataTypeService } from "app/ng2/services/data-type.service"; -import {PropertyBEModel, DataTypesMap} from "app/models"; -import {PROPERTY_DATA} from "app/utils"; -import {PROPERTY_TYPES} from "../../../../utils"; - +import { Component } from '@angular/core'; +import { DataTypesMap, PropertyBEModel } from 'app/models'; +import { DropdownValue } from 'app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component'; +import { DataTypeService } from 'app/ng2/services/data-type.service'; +import { PROPERTY_DATA } from 'app/utils'; +import * as _ from 'lodash'; +import { PROPERTY_TYPES } from '../../../../utils'; @Component({ selector: 'property-creator', templateUrl: './property-creator.component.html', - styleUrls:['./property-creator.component.less'], + styleUrls: ['./property-creator.component.less'], }) export class PropertyCreatorComponent { - typesProperties: Array; - typesSchemaProperties: Array; + typesProperties: DropdownValue[]; + typesSchemaProperties: DropdownValue[]; propertyModel: PropertyBEModel; - //propertyNameValidationPattern:RegExp = /^[a-zA-Z0-9_:-]{1,50}$/; - //commentValidationPattern:RegExp = /^[\u0000-\u00BF]*$/; - //types:Array; - dataTypes:DataTypesMap; - isLoading:boolean; + // propertyNameValidationPattern:RegExp = /^[a-zA-Z0-9_:-]{1,50}$/; + // commentValidationPattern:RegExp = /^[\u0000-\u00BF]*$/; + // types:Array; + dataTypes: DataTypesMap; + isLoading: boolean; - constructor(protected dataTypeService:DataTypeService) {} + constructor(protected dataTypeService: DataTypeService) {} ngOnInit() { this.propertyModel = new PropertyBEModel(); this.propertyModel.type = ''; this.propertyModel.schema.property.type = ''; - const types: Array = PROPERTY_DATA.TYPES; //All types - simple type + map + list - this.dataTypes = this.dataTypeService.getAllDataTypes(); //Get all data types in service - const nonPrimitiveTypes :Array = _.filter(Object.keys(this.dataTypes), (type:string)=> { - return types.indexOf(type) == -1; + const types: string[] = PROPERTY_DATA.TYPES; // All types - simple type + map + list + this.dataTypes = this.dataTypeService.getAllDataTypes(); // Get all data types in service + const nonPrimitiveTypes: string[] = _.filter(Object.keys(this.dataTypes), (type: string) => { + return types.indexOf(type) === -1; }); this.typesProperties = _.map(PROPERTY_DATA.TYPES, (type: string) => new DropdownValue(type, type) ); - let typesSimpleProperties = _.map(PROPERTY_DATA.SIMPLE_TYPES, + const typesSimpleProperties = _.map(PROPERTY_DATA.SIMPLE_TYPES, (type: string) => new DropdownValue(type, type) ); - let nonPrimitiveTypesValues = _.map(nonPrimitiveTypes, + const nonPrimitiveTypesValues = _.map(nonPrimitiveTypes, (type: string) => new DropdownValue(type, - type.replace("org.openecomp.datatypes.heat.","")) + type.replace('org.openecomp.datatypes.heat.', '')) ) .sort((a, b) => a.label.localeCompare(b.label)); - this.typesProperties = _.concat(this.typesProperties,nonPrimitiveTypesValues); - this.typesSchemaProperties = _.concat(typesSimpleProperties,nonPrimitiveTypesValues); - this.typesProperties.unshift(new DropdownValue('','Select Type...')); - this.typesSchemaProperties.unshift(new DropdownValue('','Select Schema Type...')); + this.typesProperties = _.concat(this.typesProperties, nonPrimitiveTypesValues); + this.typesSchemaProperties = _.concat(typesSimpleProperties, nonPrimitiveTypesValues); + this.typesProperties.unshift(new DropdownValue('', 'Select Type...')); + this.typesSchemaProperties.unshift(new DropdownValue('', 'Select Schema Type...')); } - checkFormValidForSubmit(){ - const showSchema:boolean = this.showSchema(); - let isSchemaValid: boolean = (showSchema && !this.propertyModel.schema.property.type)? false : true; - if (!showSchema){ + checkFormValidForSubmit() { + const showSchema: boolean = this.showSchema(); + const isSchemaValid: boolean = (showSchema && !this.propertyModel.schema.property.type) ? false : true; + if (!showSchema) { this.propertyModel.schema.property.type = ''; } return this.propertyModel.name && this.propertyModel.type && isSchemaValid; } - showSchema():boolean { + showSchema(): boolean { return [PROPERTY_TYPES.LIST, PROPERTY_TYPES.MAP].indexOf(this.propertyModel.type) > -1; - }; + } - onSchemaTypeChange():void { - if (this.propertyModel.type == PROPERTY_TYPES.MAP) { + onSchemaTypeChange(): void { + if (this.propertyModel.type === PROPERTY_TYPES.MAP) { this.propertyModel.value = JSON.stringify({'': null}); - } else if (this.propertyModel.type == PROPERTY_TYPES.LIST) { + } else if (this.propertyModel.type === PROPERTY_TYPES.LIST) { this.propertyModel.value = JSON.stringify([]); } - }; + } } diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/property-creator/property-creator.module.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/property-creator/property-creator.module.ts index 92accb26b5..1cbb4e17ec 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/property-creator/property-creator.module.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/property-creator/property-creator.module.ts @@ -1,10 +1,10 @@ -import {NgModule} from "@angular/core"; -import {CommonModule} from "@angular/common"; -import {PropertyCreatorComponent} from "./property-creator.component"; -import {FormsModule} from "@angular/forms"; -import {FormElementsModule} from "app/ng2/components/ui/form-components/form-elements.module"; -import {UiElementsModule} from "app/ng2/components/ui/ui-elements.module"; -import {TranslateModule} from "../../../shared/translator/translate.module"; +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { FormElementsModule } from 'app/ng2/components/ui/form-components/form-elements.module'; +import { UiElementsModule } from 'app/ng2/components/ui/ui-elements.module'; +import { TranslateModule } from '../../../shared/translator/translate.module'; +import { PropertyCreatorComponent } from './property-creator.component'; @NgModule({ declarations: [ diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts index 011be41611..bd7ccd1bfd 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts @@ -48,7 +48,7 @@ export class PropertiesUtils { let newFEProp: PropertyFEModel = new PropertyFEModel(property); //Convert property to FE - this.initValueObjectRef(newFEProp); //initialize valueObj. + this.initValueObjectRef(newFEProp); //initialize valueObj AND creates flattened children propertyFeArray.push(newFEProp); newFEProp.updateExpandedChildPropertyId(newFEProp.name); //display only the first level of children this.dataTypeService.checkForCustomBehavior(newFEProp); @@ -79,8 +79,8 @@ export class PropertiesUtils { return instanceFePropertiesMap; } - public convertAddPropertyBAToPropertyFE = (property: PropertyBEModel):PropertyFEModel => { - let newFEProp: PropertyFEModel = new PropertyFEModel(property); //Convert property to FE + public convertAddPropertyBAToPropertyFE = (property: PropertyBEModel): PropertyFEModel => { + const newFEProp: PropertyFEModel = new PropertyFEModel(property); //Convert property to FE this.initValueObjectRef(newFEProp); newFEProp.updateExpandedChildPropertyId(newFEProp.name); //display only the first level of children this.dataTypeService.checkForCustomBehavior(newFEProp); @@ -108,7 +108,7 @@ export class PropertiesUtils { let tempProps: Array = []; let dataTypeObj: DataTypeModel = this.dataTypeService.getDataTypeByTypeName(type); this.dataTypeService.getDerivedDataTypeProperties(dataTypeObj, tempProps, parentName); - return tempProps; + return _.sortBy(tempProps, ['propertiesName']); } /* Sets the valueObj of parent property and its children. diff --git a/catalog-ui/src/app/ng2/pages/req-and-capabilities-editor/capabilities-editor/capabilities-editor.module.ts b/catalog-ui/src/app/ng2/pages/req-and-capabilities-editor/capabilities-editor/capabilities-editor.module.ts index 1e767a5690..104a6d0579 100644 --- a/catalog-ui/src/app/ng2/pages/req-and-capabilities-editor/capabilities-editor/capabilities-editor.module.ts +++ b/catalog-ui/src/app/ng2/pages/req-and-capabilities-editor/capabilities-editor/capabilities-editor.module.ts @@ -5,7 +5,8 @@ import {FormsModule} from "@angular/forms"; import {FormElementsModule} from "app/ng2/components/ui/form-components/form-elements.module"; import {UiElementsModule} from "app/ng2/components/ui/ui-elements.module"; import {TranslateModule} from 'app/ng2/shared/translator/translate.module'; -import {SdcUiComponentsModule} from "sdc-ui/lib/angular/index"; +import { SdcUiComponentsModule } from 'onap-ui-angular'; + @NgModule({ declarations: [ diff --git a/catalog-ui/src/app/ng2/pages/req-and-capabilities-editor/requirements-editor/requirements-editor.module.ts b/catalog-ui/src/app/ng2/pages/req-and-capabilities-editor/requirements-editor/requirements-editor.module.ts index 1be8be51af..d38790a8db 100644 --- a/catalog-ui/src/app/ng2/pages/req-and-capabilities-editor/requirements-editor/requirements-editor.module.ts +++ b/catalog-ui/src/app/ng2/pages/req-and-capabilities-editor/requirements-editor/requirements-editor.module.ts @@ -4,7 +4,7 @@ import {RequirementsEditorComponent} from "./requirements-editor.component"; import {FormsModule} from "@angular/forms"; import {FormElementsModule} from "../../../components/ui/form-components/form-elements.module"; import {TranslateModule} from 'app/ng2/shared/translator/translate.module'; -import {SdcUiComponentsModule} from "sdc-ui/lib/angular/index"; +import { SdcUiComponentsModule } from "onap-ui-angular"; @NgModule({ declarations: [ diff --git a/catalog-ui/src/app/ng2/pages/service-consumption-editor/service-consumption-editor.component.ts b/catalog-ui/src/app/ng2/pages/service-consumption-editor/service-consumption-editor.component.ts index 2c86cc5c5c..8444c6261a 100644 --- a/catalog-ui/src/app/ng2/pages/service-consumption-editor/service-consumption-editor.component.ts +++ b/catalog-ui/src/app/ng2/pages/service-consumption-editor/service-consumption-editor.component.ts @@ -14,29 +14,29 @@ * permissions and limitations under the License. */ -import * as _ from "lodash"; import { Component } from '@angular/core'; -import {ServiceServiceNg2} from "app/ng2/services/component-services/service.service"; import { - Service, - ServiceInstanceObject, - InstanceFePropertiesMap, - InstanceBePropertiesMap, - PropertyBEModel, + Capability, InputBEModel, - OperationModel, + InstanceBePropertiesMap, + InstanceFePropertiesMap, InterfaceModel, - Capability + OperationModel, + PropertyBEModel, + Service } from 'app/models'; -import {ConsumptionInput, ConsumptionInputDetails, ServiceOperation} from 'app/ng2/components/logic/service-consumption/service-consumption.component'; -import {PropertiesUtils} from "app/ng2/pages/properties-assignment/services/properties.utils"; +import { ConsumptionInput, ConsumptionInputDetails, ServiceOperation } from 'app/ng2/components/logic/service-consumption/service-consumption.component'; +import { PropertiesUtils } from 'app/ng2/pages/properties-assignment/services/properties.utils'; +import { ServiceServiceNg2 } from 'app/ng2/services/component-services/service.service'; import { PROPERTY_DATA } from 'app/utils'; - +import * as _ from 'lodash'; +import { ServiceInstanceObject } from '../../../models/service-instance-properties-and-interfaces'; +import { TopologyTemplateService } from '../../services/component-services/topology-template.service'; @Component({ selector: 'service-consumption-editor', templateUrl: './service-consumption-editor.component.html', - styleUrls:['./service-consumption-editor.component.less'], + styleUrls: ['./service-consumption-editor.component.less'], providers: [] }) @@ -45,27 +45,27 @@ export class ServiceConsumptionCreatorComponent { input: { interfaceId: string, serviceOperationIndex: number, - serviceOperations: Array, + serviceOperations: ServiceOperation[], parentService: Service, selectedService: Service, - parentServiceInputs: Array, - selectedServiceProperties: Array, - selectedServiceInstanceId: String, - selectedInstanceSiblings: Array, - selectedInstanceCapabilitisList: Array, - siblingsCapabilitiesList: Map> + parentServiceInputs: InputBEModel[], + selectedServiceProperties: PropertyBEModel[], + selectedServiceInstanceId: string, + selectedInstanceSiblings: ServiceInstanceObject[], + selectedInstanceCapabilitisList: Capability[], + siblingsCapabilitiesList: Map }; - sourceTypes: Array = []; - serviceOperationsList: Array; + sourceTypes: any[] = []; + serviceOperationsList: ServiceOperation[]; serviceOperation: ServiceOperation; currentIndex: number; isLoading: boolean = false; parentService: Service; selectedService: Service; - selectedServiceInstanceId: String; - parentServiceInputs: Array; - selectedServiceProperties: Array; - changedData: Array = []; + selectedServiceInstanceId: string; + parentServiceInputs: InputBEModel[]; + selectedServiceProperties: PropertyBEModel[]; + changedData: ConsumptionInputDetails[] = []; inputFePropertiesMap: any = []; SOURCE_TYPES = { @@ -75,7 +75,7 @@ export class ServiceConsumptionCreatorComponent { SERVICE_INPUT_LABEL: 'Service Input' }; - constructor(private serviceServiceNg2: ServiceServiceNg2, private propertiesUtils:PropertiesUtils) {} + constructor(private topologyTemplateService: TopologyTemplateService, private propertiesUtils: PropertiesUtils) {} ngOnInit() { this.serviceOperationsList = this.input.serviceOperations; @@ -112,7 +112,7 @@ export class ServiceConsumptionCreatorComponent { capabilities: [] } ]; - _.forEach(this.input.selectedInstanceSiblings, sib => + _.forEach(this.input.selectedInstanceSiblings, (sib) => this.sourceTypes.push({ label: sib.name, value: sib.id, @@ -128,56 +128,84 @@ export class ServiceConsumptionCreatorComponent { } onExpandAll() { - _.forEach(this.serviceOperation.consumptionInputs, coInput => { + _.forEach(this.serviceOperation.consumptionInputs, (coInput) => { coInput.expanded = true; - }) + }); } onCollapseAll() { - _.forEach(this.serviceOperation.consumptionInputs, coInput => { + _.forEach(this.serviceOperation.consumptionInputs, (coInput) => { coInput.expanded = false; - }) + }); } isAllInputExpanded() { - return _.every(this.serviceOperation.consumptionInputs, coInput => coInput.expanded === true); + return _.every(this.serviceOperation.consumptionInputs, (coInput) => coInput.expanded === true); } isAllInputCollapsed() { - return _.every(this.serviceOperation.consumptionInputs, coInput => coInput.expanded === false); + return _.every(this.serviceOperation.consumptionInputs, (coInput) => coInput.expanded === false); } onChangePage(newIndex) { if (newIndex >= 0 && newIndex < this.serviceOperationsList.length) { this.currentIndex = newIndex; this.serviceOperation = this.serviceOperationsList[newIndex]; - if(!this.serviceOperation.consumptionInputs || this.serviceOperation.consumptionInputs.length === 0) { + if (!this.serviceOperation.consumptionInputs || this.serviceOperation.consumptionInputs.length === 0) { this.initConsumptionInputs(); } this.getComplexPropertiesForCurrentInputsOfOperation(this.serviceOperation.consumptionInputs); } } + checkFormValidForSubmit(): boolean { + return this.isValidInputsValues() && this.isMandatoryFieldsValid(); + } + + checkFormValidForNavigation(): boolean { + return this.isMandatoryFieldsValid() && (this.changedData.length === 0 || this.isValidInputsValues()); + } + + onChange(value: any, isValid: boolean, consumptionInput: ConsumptionInputDetails) { + consumptionInput.updateValidity(isValid); + const dataChangedIndex = this.changedData.findIndex((changedItem) => changedItem.inputId === consumptionInput.inputId); + if (value !== consumptionInput.origVal) { + if (dataChangedIndex === -1) { + this.changedData.push(consumptionInput); + } + } else { + if (dataChangedIndex !== -1) { + this.changedData.splice(dataChangedIndex, 1); + } + } + } + + onComplexPropertyChanged(property, consumptionInput) { + consumptionInput.value = JSON.stringify(property.valueObj); + this.onChange(property.valueObj, property.valueObjIsValid , consumptionInput); + } + private initConsumptionInputs() { this.isLoading = true; - this.serviceServiceNg2.getServiceConsumptionInputs(this.parentService, this.selectedServiceInstanceId, this.input.interfaceId, this.serviceOperation.operation).subscribe((result: Array) => { + this.topologyTemplateService.getServiceConsumptionInputs(this.parentService.uniqueId, this.selectedServiceInstanceId, + this.input.interfaceId, this.serviceOperation.operation).subscribe((result: ConsumptionInput[]) => { this.isLoading = false; this.serviceOperation.consumptionInputs = this.analyzeCurrentConsumptionInputs(result); this.getComplexPropertiesForCurrentInputsOfOperation(this.serviceOperation.consumptionInputs); - }, err=> { + }, (err) => { this.isLoading = false; }); } - private analyzeCurrentConsumptionInputs(result: Array): Array { - let inputsResult: Array = []; - let currentOp = this.serviceOperation.operation; - if(currentOp) { - inputsResult = _.map(result, input => { - let sourceVal = input.source || this.SOURCE_TYPES.STATIC; - let consumptionInputDetails: ConsumptionInputDetails = _.cloneDeep(input); + private analyzeCurrentConsumptionInputs(result: any[]): ConsumptionInputDetails[] { + let inputsResult: ConsumptionInputDetails[] = []; + const currentOp = this.serviceOperation.operation; + if (currentOp) { + inputsResult = _.map(result, (input) => { + const sourceVal = input.source || this.SOURCE_TYPES.STATIC; + const consumptionInputDetails: ConsumptionInputDetails = _.cloneDeep(input); consumptionInputDetails.source = sourceVal; consumptionInputDetails.isValid = true; consumptionInputDetails.expanded = false; - let filteredListsObj = this.getFilteredProps(sourceVal, input.type); + const filteredListsObj = this.getFilteredProps(sourceVal, input.type); consumptionInputDetails.assignValueLabel = this.getAssignValueLabel(sourceVal); consumptionInputDetails.associatedProps = filteredListsObj.associatedPropsList; consumptionInputDetails.associatedInterfaces = filteredListsObj.associatedInterfacesList; @@ -190,15 +218,14 @@ export class ServiceConsumptionCreatorComponent { private onSourceChanged(consumptionInput: ConsumptionInputDetails): void { consumptionInput.assignValueLabel = this.getAssignValueLabel(consumptionInput.source); - let filteredListsObj = this.getFilteredProps(consumptionInput.source, consumptionInput.type); + const filteredListsObj = this.getFilteredProps(consumptionInput.source, consumptionInput.type); consumptionInput.associatedProps = filteredListsObj.associatedPropsList; consumptionInput.associatedInterfaces = filteredListsObj.associatedInterfacesList; consumptionInput.associatedCapabilities = filteredListsObj.associatedCapabilitiesList; - if(consumptionInput.source === this.SOURCE_TYPES.STATIC) { - if(PROPERTY_DATA.SIMPLE_TYPES.indexOf(consumptionInput.type) !== -1) { - consumptionInput.value = consumptionInput.defaultValue || ""; - } - else { + if (consumptionInput.source === this.SOURCE_TYPES.STATIC) { + if (PROPERTY_DATA.SIMPLE_TYPES.indexOf(consumptionInput.type) !== -1) { + consumptionInput.value = consumptionInput.defaultValue || ''; + } else { consumptionInput.value = null; Object.assign(this.inputFePropertiesMap, this.processPropertiesOfComplexTypeInput(consumptionInput)); } @@ -206,9 +233,11 @@ export class ServiceConsumptionCreatorComponent { } private getFilteredProps(sourceVal, inputType) { - let currentSourceObj = this.sourceTypes.find(s => s.value === sourceVal); - let associatedInterfacesList = [], associatedPropsList = [], associatedCapabilitiesPropsList: Array = []; - if(currentSourceObj) { + const currentSourceObj = this.sourceTypes.find((s) => s.value === sourceVal); + let associatedInterfacesList = []; + let associatedPropsList = []; + let associatedCapabilitiesPropsList: Capability[] = []; + if (currentSourceObj) { if (currentSourceObj.interfaces) { associatedInterfacesList = this.getFilteredInterfaceOutputs(currentSourceObj, inputType); } @@ -221,31 +250,31 @@ export class ServiceConsumptionCreatorComponent { associatedCapabilitiesPropsList = _.reduce(currentSourceObj.capabilities, (filteredCapsList, capability: Capability) => { - let filteredProps = _.filter(capability.properties, prop => prop.type === inputType); + const filteredProps = _.filter(capability.properties, (prop) => prop.type === inputType); if (filteredProps.length) { - let cap = new Capability(capability); + const cap = new Capability(capability); cap.properties = filteredProps; filteredCapsList.push(cap); } - return filteredCapsList + return filteredCapsList; }, []); } return { - associatedPropsList: associatedPropsList, - associatedInterfacesList: associatedInterfacesList, + associatedPropsList, + associatedInterfacesList, associatedCapabilitiesList: associatedCapabilitiesPropsList - } + }; } private getFilteredInterfaceOutputs(currentSourceObj, inputType) { - let currentServiceOperationId = this.serviceOperation.operation.uniqueId; - let filteredInterfacesList = []; - Object.keys(currentSourceObj.interfaces).map(interfId => { - let interfaceObj: InterfaceModel = new InterfaceModel(currentSourceObj.interfaces[interfId]); - Object.keys(interfaceObj.operations).map(opId => { - if(currentServiceOperationId !== opId) { - let operationObj: OperationModel = interfaceObj.operations[opId]; - let filteredOutputsList = _.filter(operationObj.outputs.listToscaDataDefinition, output => output.type === inputType); + const currentServiceOperationId = this.serviceOperation.operation.uniqueId; + const filteredInterfacesList = []; + Object.keys(currentSourceObj.interfaces).map((interfId) => { + const interfaceObj: InterfaceModel = new InterfaceModel(currentSourceObj.interfaces[interfId]); + Object.keys(interfaceObj.operations).map((opId) => { + if (currentServiceOperationId !== opId) { + const operationObj: OperationModel = interfaceObj.operations[opId]; + const filteredOutputsList = _.filter(operationObj.outputs.listToscaDataDefinition, (output) => output.type === inputType); if (filteredOutputsList.length) { filteredInterfacesList.push({ name: `${interfaceObj.type}.${operationObj.name}`, @@ -259,25 +288,23 @@ export class ServiceConsumptionCreatorComponent { return filteredInterfacesList; } - getAssignValueLabel(selectedSource: string): string { - if(selectedSource === this.SOURCE_TYPES.STATIC || selectedSource === "") { + private getAssignValueLabel(selectedSource: string): string { + if (selectedSource === this.SOURCE_TYPES.STATIC || selectedSource === '') { return this.SOURCE_TYPES.STATIC; - } - else { - if(selectedSource === this.parentService.uniqueId) { //parent is the source + } else { + if (selectedSource === this.parentService.uniqueId) { // parent is the source return this.SOURCE_TYPES.SERVICE_INPUT_LABEL; } return this.SOURCE_TYPES.SERVICE_PROPERTY_LABEL; } } - private isValidInputsValues(): boolean { return this.changedData.length > 0 && this.changedData.every((changedItem) => changedItem.isValid); } private isMandatoryFieldsValid(): boolean { - const invalid: Array = this.serviceOperation.consumptionInputs.filter(item => + const invalid: ConsumptionInputDetails[] = this.serviceOperation.consumptionInputs.filter((item) => item.required && (item.value === null || typeof item.value === 'undefined' || item.value === '')); if (invalid.length > 0) { return false; @@ -285,45 +312,19 @@ export class ServiceConsumptionCreatorComponent { return true; } - checkFormValidForSubmit(): boolean { - return this.isValidInputsValues() && this.isMandatoryFieldsValid(); - } - - checkFormValidForNavigation(): boolean { - return this.isMandatoryFieldsValid() && (this.changedData.length === 0 || this.isValidInputsValues()); - } - - onChange(value: any, isValid: boolean, consumptionInput: ConsumptionInputDetails) { - consumptionInput.updateValidity(isValid); - const dataChangedIndex = this.changedData.findIndex((changedItem) => changedItem.inputId === consumptionInput.inputId); - if (value !== consumptionInput.origVal) { - if (dataChangedIndex === -1) { - this.changedData.push(consumptionInput); - } - } else { - if (dataChangedIndex !== -1) { - this.changedData.splice(dataChangedIndex, 1); - } - } - } - - private getComplexPropertiesForCurrentInputsOfOperation(opInputs: Array) { - _.forEach(opInputs, input => { - if(PROPERTY_DATA.SIMPLE_TYPES.indexOf(input.type) === -1 && input.source === this.SOURCE_TYPES.STATIC) { + private getComplexPropertiesForCurrentInputsOfOperation(opInputs: ConsumptionInput[]) { + _.forEach(opInputs, (input) => { + if (PROPERTY_DATA.SIMPLE_TYPES.indexOf(input.type) === -1 && input.source === this.SOURCE_TYPES.STATIC) { Object.assign(this.inputFePropertiesMap, this.processPropertiesOfComplexTypeInput(input)); } }); } private processPropertiesOfComplexTypeInput(input: ConsumptionInput): InstanceFePropertiesMap { - let inputBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap(); + const inputBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap(); inputBePropertiesMap[input.name] = [input]; - let originTypeIsVF = false; - return this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(inputBePropertiesMap, originTypeIsVF); //create flattened children and init values + const originTypeIsVF = false; + return this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(inputBePropertiesMap, originTypeIsVF); // create flattened children and init values } - onComplexPropertyChanged(property, consumptionInput) { - consumptionInput.value = JSON.stringify(property.valueObj); - this.onChange(property.valueObj, property.valueObjIsValid , consumptionInput); - } -} \ No newline at end of file +} diff --git a/catalog-ui/src/app/ng2/pages/service-consumption-editor/service-consumption-editor.module.ts b/catalog-ui/src/app/ng2/pages/service-consumption-editor/service-consumption-editor.module.ts index e37cd76716..43e88eb0dc 100644 --- a/catalog-ui/src/app/ng2/pages/service-consumption-editor/service-consumption-editor.module.ts +++ b/catalog-ui/src/app/ng2/pages/service-consumption-editor/service-consumption-editor.module.ts @@ -1,11 +1,11 @@ -import { NgModule } from "@angular/core"; -import {CommonModule} from "@angular/common"; -import {ServiceConsumptionCreatorComponent} from "./service-consumption-editor.component"; -import {FormsModule} from "@angular/forms"; -import {FormElementsModule} from "app/ng2/components/ui/form-components/form-elements.module"; -import {UiElementsModule} from "app/ng2/components/ui/ui-elements.module"; -import {PropertyTableModule} from 'app/ng2/components/logic/properties-table/property-table.module'; -import {TranslateModule} from 'app/ng2/shared/translator/translate.module'; +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { PropertyTableModule } from 'app/ng2/components/logic/properties-table/property-table.module'; +import { FormElementsModule } from 'app/ng2/components/ui/form-components/form-elements.module'; +import { UiElementsModule } from 'app/ng2/components/ui/ui-elements.module'; +import { TranslateModule } from 'app/ng2/shared/translator/translate.module'; +import { ServiceConsumptionCreatorComponent } from './service-consumption-editor.component'; @NgModule({ declarations: [ @@ -25,4 +25,4 @@ import {TranslateModule} from 'app/ng2/shared/translator/translate.module'; providers: [] }) export class ServiceConsumptionCreatorModule { -} \ No newline at end of file +} diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts index 271dd4ada0..708742ae0c 100644 --- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts +++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts @@ -14,20 +14,23 @@ * permissions and limitations under the License. */ import { Component } from '@angular/core'; -import {ServiceServiceNg2} from "app/ng2/services/component-services/service.service"; -import {ConstraintObjectUI, OPERATOR_TYPES} from 'app/ng2/components/logic/service-dependencies/service-dependencies.component'; -import {ServiceInstanceObject, PropertyBEModel, InputBEModel} from 'app/models'; +import { InputBEModel, PropertyBEModel } from 'app/models'; +import { ConstraintObjectUI, OPERATOR_TYPES } from 'app/ng2/components/logic/service-dependencies/service-dependencies.component'; +import { DropdownValue } from 'app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component'; +import { ServiceServiceNg2 } from 'app/ng2/services/component-services/service.service'; import { PROPERTY_DATA } from 'app/utils'; -import {DropdownValue} from 'app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component'; +import { ServiceInstanceObject } from '../../../models/service-instance-properties-and-interfaces'; -export class UIDropDownSourceTypesElement extends DropdownValue{ - options: Array; +export class UIDropDownSourceTypesElement extends DropdownValue { + options: any[]; assignedLabel: string; type: string; - constructor(input?: any){ - if(input) { - let value = input.value || ''; - let label = input.label || ''; + constructor(input?: any) { + if (input) { + const value = input.value || ''; + const label = input.label || ''; + // const hidden = input.hidden || ''; + // const selected = input.selected || ''; super(value, label); this.options = input.options; this.assignedLabel = input.assignedLabel; @@ -36,10 +39,11 @@ export class UIDropDownSourceTypesElement extends DropdownValue{ } } +// tslint:disable-next-line:max-classes-per-file @Component({ selector: 'service-dependencies-editor', templateUrl: './service-dependencies-editor.component.html', - styleUrls:['./service-dependencies-editor.component.less'], + styleUrls: ['./service-dependencies-editor.component.less'], providers: [ServiceServiceNg2] }) @@ -47,44 +51,42 @@ export class ServiceDependenciesEditorComponent { input: { serviceRuleIndex: number, - serviceRules: Array, + serviceRules: ConstraintObjectUI[], compositeServiceName: string, currentServiceName: string, - parentServiceInputs: Array, - selectedInstanceProperties: Array, - operatorTypes: Array, - selectedInstanceSiblings: Array + parentServiceInputs: InputBEModel[], + selectedInstanceProperties: PropertyBEModel[], + operatorTypes: DropdownValue[], + selectedInstanceSiblings: ServiceInstanceObject[] }; currentServiceName: string; - selectedServiceProperties: Array; + selectedServiceProperties: PropertyBEModel[]; selectedPropertyObj: PropertyBEModel; - ddValueSelectedServicePropertiesNames: Array; - operatorTypes: Array; - sourceTypes: Array = []; + ddValueSelectedServicePropertiesNames: DropdownValue[]; + operatorTypes: DropdownValue[]; + sourceTypes: UIDropDownSourceTypesElement[] = []; currentRule: ConstraintObjectUI; currentIndex: number; - listOfValuesToAssign: Array; - listOfSourceOptions: Array; + listOfValuesToAssign: DropdownValue[]; + listOfSourceOptions: PropertyBEModel[]; assignedValueLabel: string; - serviceRulesList: Array; - + serviceRulesList: ConstraintObjectUI[]; SOURCE_TYPES = { STATIC: {label: 'Static', value: 'static'}, SERVICE_PROPERTY: {label: 'Service Property', value: 'property'} }; - ngOnInit() { this.currentIndex = this.input.serviceRuleIndex; this.serviceRulesList = this.input.serviceRules; this.currentRule = this.serviceRulesList && this.input.serviceRuleIndex >= 0 ? - this.serviceRulesList[this.input.serviceRuleIndex]: - new ConstraintObjectUI({sourceName: this.SOURCE_TYPES.STATIC.value, sourceType: this.SOURCE_TYPES.STATIC.value, value: "", constraintOperator: OPERATOR_TYPES.EQUAL}); + this.serviceRulesList[this.input.serviceRuleIndex] : + new ConstraintObjectUI({sourceName: this.SOURCE_TYPES.STATIC.value, sourceType: this.SOURCE_TYPES.STATIC.value, value: '', constraintOperator: OPERATOR_TYPES.EQUAL}); this.currentServiceName = this.input.currentServiceName; this.operatorTypes = this.input.operatorTypes; this.selectedServiceProperties = this.input.selectedInstanceProperties; - this.ddValueSelectedServicePropertiesNames = _.map(this.input.selectedInstanceProperties, prop => new DropdownValue(prop.name, prop.name)); + this.ddValueSelectedServicePropertiesNames = _.map(this.input.selectedInstanceProperties, (prop) => new DropdownValue(prop.name, prop.name)); this.initSourceTypes(); this.syncRuleData(); this.updateSourceTypesRelatedValues(); @@ -100,7 +102,7 @@ export class ServiceDependenciesEditorComponent { type: this.SOURCE_TYPES.SERVICE_PROPERTY.value, options: this.input.parentServiceInputs }); - _.forEach(this.input.selectedInstanceSiblings, sib => + _.forEach(this.input.selectedInstanceSiblings, (sib) => this.sourceTypes.push({ label: sib.name, value: sib.name, @@ -112,28 +114,27 @@ export class ServiceDependenciesEditorComponent { } syncRuleData() { - if(!this.currentRule.sourceName && this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value) { + if (!this.currentRule.sourceName && this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value) { this.currentRule.sourceName = this.SOURCE_TYPES.STATIC.value; } - this.selectedPropertyObj = _.find(this.selectedServiceProperties, prop => prop.name === this.currentRule.servicePropertyName); + this.selectedPropertyObj = _.find(this.selectedServiceProperties, (prop) => prop.name === this.currentRule.servicePropertyName); this.updateOperatorTypesList(); this.updateSourceTypesRelatedValues(); } updateOperatorTypesList() { if (this.selectedPropertyObj && PROPERTY_DATA.SIMPLE_TYPES_COMPARABLE.indexOf(this.selectedPropertyObj.type) === -1) { - this.operatorTypes = [{label: "=", value: OPERATOR_TYPES.EQUAL}]; + this.operatorTypes = [{label: '=', value: OPERATOR_TYPES.EQUAL}]; this.currentRule.constraintOperator = OPERATOR_TYPES.EQUAL; - } - else { + } else { this.operatorTypes = this.input.operatorTypes; } } updateSourceTypesRelatedValues() { - if(this.currentRule.sourceName) { - let selectedSourceType: UIDropDownSourceTypesElement = this.sourceTypes.find( - t => t.value === this.currentRule.sourceName && t.type === this.currentRule.sourceType + if (this.currentRule.sourceName) { + const selectedSourceType: UIDropDownSourceTypesElement = this.sourceTypes.find( + (t) => t.value === this.currentRule.sourceName && t.type === this.currentRule.sourceType ); this.listOfSourceOptions = selectedSourceType.options || []; this.assignedValueLabel = selectedSourceType.assignedLabel || this.SOURCE_TYPES.STATIC.label; @@ -150,7 +151,7 @@ export class ServiceDependenciesEditorComponent { } onServicePropertyChanged() { - this.selectedPropertyObj = _.find(this.selectedServiceProperties, prop => prop.name === this.currentRule.servicePropertyName); + this.selectedPropertyObj = _.find(this.selectedServiceProperties, (prop) => prop.name === this.currentRule.servicePropertyName); this.updateOperatorTypesList(); this.filterOptionsByType(); this.currentRule.value = ''; @@ -165,11 +166,11 @@ export class ServiceDependenciesEditorComponent { } filterOptionsByType() { - if(!this.selectedPropertyObj) { + if (!this.selectedPropertyObj) { this.listOfValuesToAssign = []; return; } - this.listOfValuesToAssign = this.listOfSourceOptions.reduce((result, op:PropertyBEModel) => { + this.listOfValuesToAssign = this.listOfSourceOptions.reduce((result, op: PropertyBEModel) => { if (op.type === this.selectedPropertyObj.type && (!op.schemaType || op.schemaType === this.selectedPropertyObj.schemaType)) { result.push(new DropdownValue(op.name, op.name)); } @@ -182,11 +183,11 @@ export class ServiceDependenciesEditorComponent { } checkFormValidForSubmit() { - if(!this.serviceRulesList) { //for create modal - let isStatic = this.currentRule.sourceName === this.SOURCE_TYPES.STATIC.value; + if (!this.serviceRulesList) { // for create modal + const isStatic = this.currentRule.sourceName === this.SOURCE_TYPES.STATIC.value; return this.currentRule.isValidRule(isStatic); } - //for update all rules - return this.serviceRulesList.every(rule => rule.isValidRule(rule.sourceName === this.SOURCE_TYPES.STATIC.value)); + // for update all rules + return this.serviceRulesList.every((rule) => rule.isValidRule(rule.sourceName === this.SOURCE_TYPES.STATIC.value)); } -} \ No newline at end of file +} diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts index 98ac997bf7..7b128f4468 100644 --- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts +++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts @@ -1,9 +1,9 @@ -import { NgModule } from "@angular/core"; -import {CommonModule} from "@angular/common"; -import {ServiceDependenciesEditorComponent} from "./service-dependencies-editor.component"; -import {FormsModule} from "@angular/forms"; -import {FormElementsModule} from "app/ng2/components/ui/form-components/form-elements.module"; -import {UiElementsModule} from "app/ng2/components/ui/ui-elements.module"; +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { FormElementsModule } from 'app/ng2/components/ui/form-components/form-elements.module'; +import { UiElementsModule } from 'app/ng2/components/ui/ui-elements.module'; +import { ServiceDependenciesEditorComponent } from './service-dependencies-editor.component'; @NgModule({ declarations: [ @@ -22,4 +22,4 @@ import {UiElementsModule} from "app/ng2/components/ui/ui-elements.module"; providers: [] }) export class ServiceDependenciesEditorModule { -} \ No newline at end of file +} diff --git a/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.html b/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.html deleted file mode 100644 index 0abdda1cc6..0000000000 --- a/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - -
- - -
diff --git a/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.less b/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.less deleted file mode 100644 index beec9bd567..0000000000 --- a/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.less +++ /dev/null @@ -1,21 +0,0 @@ -@import './../../../../../assets/styles/variables.less'; -.remove { - display: flex; - align-items: center; - justify-content: center; -} - -.cell { - padding: 0; -} - -/deep/ .link-selector { - select { - height: 30px; - border: none; - stroke: none; - } - -} - - diff --git a/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.ts b/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.ts deleted file mode 100644 index e4fc1d4522..0000000000 --- a/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link-row.component.ts +++ /dev/null @@ -1,103 +0,0 @@ -import {Component, Input} from '@angular/core'; -import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component"; -import {Link} from './link.model'; -import {ServicePathMapItem} from "app/models/graph/nodes-and-links-map"; - -@Component({ - selector: 'link-row', - templateUrl: './link-row.component.html', - styleUrls: ['./link-row.component.less'] -}) - - -export class LinkRowComponent { - @Input() data:Array; - @Input() link:Link; - @Input() removeRow:Function; - source: Array = []; - target: Array = []; - srcCP: Array = []; - targetCP: Array = []; - - ngOnChanges() { - if (this.data) { - this.parseInitialData(this.data); - } - } - - parseInitialData(data: Array) { - this.source = this.convertValuesToDropDownOptions(data); - if (this.link.fromNode) { - let srcCPOptions = this.findOptions(data, this.link.fromNode); - if (!srcCPOptions) { return; } - this.srcCP = this.convertValuesToDropDownOptions(srcCPOptions); - if (this.link.fromCP) { - this.target = this.convertValuesToDropDownOptions(data); - if (this.link.toNode) { - let targetCPOptions = this.findOptions(data, this.link.toNode); - if (!targetCPOptions) { return; } - this.targetCP = this.convertValuesToDropDownOptions(targetCPOptions); - } - } - } - } - - private findOptions(items: Array, nodeOrCPId: string) { - let item = _.find(items, (dataItem) => nodeOrCPId === dataItem.id); - if (item && item.data && item.data.options) { - return item.data.options; - } - console.warn('no option was found to match selection of Node/CP with id:' + nodeOrCPId); - return null; - } - - private convertValuesToDropDownOptions(values: Array): Array { - let result:Array = []; - for (let i = 0; i < values.length ; i++) { - result[result.length] = new DropdownValue(values[i].id, values[i].data.name); - } - return result.sort((a, b) => a.label.localeCompare(b.label)); - } - - onSourceSelected(id) { - if (id) { - let srcCPOptions = this.findOptions(this.data, id); - this.srcCP = this.convertValuesToDropDownOptions(srcCPOptions); - this.link.fromCP = ''; - this.link.toNode = ''; - this.link.toCP = ''; - this.target = []; - this.targetCP = []; - } - } - - onSrcCPSelected (id) { - if (id) { - let srcCPOptions = this.findOptions(this.data, this.link.fromNode); - let srcCPData = srcCPOptions.find(option => id === option.id).data; - this.target = this.convertValuesToDropDownOptions(this.data); - this.link.fromCPOriginId = srcCPData.ownerId; - this.link.toNode = ''; - this.link.toCP = ''; - this.targetCP = []; - } - - } - - onTargetSelected(id) { - if (id) { - let targetCPOptions = this.findOptions(this.data, id); - this.targetCP = this.convertValuesToDropDownOptions(targetCPOptions); - this.link.toCP = ''; - } - - } - - onTargetCPSelected(id) { - if (id) { - let targetCPOptions = this.findOptions(this.data, this.link.toNode); - let targetCPDataObj = targetCPOptions.find(option => id === option.id).data; - this.link.toCPOriginId = targetCPDataObj.ownerId; - } - } -} diff --git a/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link.model.ts b/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link.model.ts deleted file mode 100644 index 80128eb42e..0000000000 --- a/catalog-ui/src/app/ng2/pages/service-path-creator/link-row/link.model.ts +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * ============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========================================================= - */ -'use strict'; -import {ForwardingPathLink} from "app/models/forwarding-path-link"; - -export class Link extends ForwardingPathLink { - public canEdit:boolean = false; - public canRemove:boolean = false; - public isFirst:boolean = false; - - constructor(link: ForwardingPathLink, canEdit: boolean, canRemove: boolean, isFirst: boolean) { - super(link.fromNode,link.fromCP, link.toNode, link.toCP, link.fromCPOriginId, link.toCPOriginId); - this.canEdit = canEdit; - this.canRemove = canRemove; - this.isFirst = isFirst; - } -} - - diff --git a/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.html b/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.html deleted file mode 100644 index cc14b4961f..0000000000 --- a/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.html +++ /dev/null @@ -1,56 +0,0 @@ - - -
-
-
- - -
- -
-
- - -
-
- - -
-
- -
- Based On - Extend Flow -
- -
-
-
- {{header}} -
-
-
- There is no data to display -
-
- -
-
- - -
-
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.less b/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.less deleted file mode 100644 index 5c9e53e229..0000000000 --- a/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.less +++ /dev/null @@ -1,45 +0,0 @@ -@import './../../../../assets/styles/variables.less'; -.service-path-creator { - font-family: @font-opensans-regular; - .separator-buttons { - margin: 10px 0; - display: flex; - justify-content: space-between; - } - .i-sdc-form-label { - font-size: 12px; - } - .w-sdc-form .i-sdc-form-item { - margin-bottom: 15px; - } - - .side-by-side { - display: flex; - .i-sdc-form-item { - flex-basis: 100%; - &:first-child { - margin-right: 10px; - } - } - } - - .generic-table { - max-height: 233px; - .header-row .header-cell { - &:last-child { - padding: 0; - } - } - /deep/ .cell { - &:last-child { - min-width: 30px; - } - } - } - - .based-on-title { - text-transform: uppercase; - font-size: 18px; - font-family: @font-opensans-regular; - } -} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.ts b/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.ts deleted file mode 100644 index bffb1c5e7e..0000000000 --- a/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.component.ts +++ /dev/null @@ -1,147 +0,0 @@ -/*- - * ============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========================================================= - */ - -import * as _ from "lodash"; -import { Component, ElementRef, forwardRef, Inject } from '@angular/core'; -import {Link} from './link-row/link.model'; -import {ForwardingPath} from 'app/models/forwarding-path'; -import {ServiceServiceNg2} from "app/ng2/services/component-services/service.service"; -import {ForwardingPathLink} from "app/models/forwarding-path-link"; -import {ServicePathMapItem} from "app/models/graph/nodes-and-links-map"; - -@Component({ - selector: 'service-path-creator', - templateUrl: './service-path-creator.component.html', - styleUrls:['./service-path-creator.component.less'], - providers: [ServiceServiceNg2] -}) - -export class ServicePathCreatorComponent { - - linksMap:Array; - links:Array = []; - input:any; - headers: Array = []; - removeRow: Function; - forwardingPath:ForwardingPath; - //isExtendAllowed:boolean = false; - - constructor(private serviceService: ServiceServiceNg2) { - this.forwardingPath = new ForwardingPath(); - this.links = [new Link(new ForwardingPathLink('', '', '', '', '', ''), true, false, true)]; - this.headers = ['Source', 'Source Connection Point', 'Target', 'Target Connection Point', ' ']; - this.removeRow = () => { - if (this.links.length === 1) { - return; - } - this.links.splice(this.links.length-1, 1); - this.enableCurrentRow(); - }; - } - - ngOnInit() { - this.serviceService.getNodesAndLinksMap(this.input.service).subscribe((res:any) => { - this.linksMap = res; - }); - this.processExistingPath(); - - } - - private processExistingPath() { - if (this.input.pathId) { - let forwardingPath = {...this.input.service.forwardingPaths[this.input.pathId]}; - this.forwardingPath.name = forwardingPath.name; - this.forwardingPath.destinationPortNumber = forwardingPath.destinationPortNumber; - this.forwardingPath.protocol = forwardingPath.protocol; - this.forwardingPath.uniqueId = forwardingPath.uniqueId; - this.links = []; - _.forEach(forwardingPath.pathElements.listToscaDataDefinition, (link:ForwardingPathLink) => { - this.links[this.links.length] = new Link(link, false, false, false); - }); - this.links[this.links.length - 1].canEdit = true; - this.links[this.links.length - 1].canRemove = true; - this.links[0].isFirst = true; - } - } - - isExtendAllowed():boolean { - if (this.links[this.links.length-1].toCP) { - return true; - } - return false; - } - - enableCurrentRow() { - this.links[this.links.length-1].canEdit = true; - if (this.links.length !== 1) { - this.links[this.links.length-1].canRemove = true; - } - } - - addRow() { - this.disableRows(); - this.links[this.links.length] = new Link( - new ForwardingPathLink(this.links[this.links.length-1].toNode, - this.links[this.links.length-1].toCP, - '', - '', - this.links[this.links.length-1].toCPOriginId, - '' - ), - true, - true, - false - ); - } - - disableRows() { - for (let i = 0 ; i < this.links.length ; i++) { - this.links[i].canEdit = false; - this.links[i].canRemove = false; - } - } - - createPathLinksObject() { - for (let i = 0 ; i < this.links.length ; i++) { - let link = this.links[i]; - this.forwardingPath.addPathLink(link.fromNode, link.fromCP, link.toNode, link.toCP, link.fromCPOriginId, link.toCPOriginId); - } - } - - createServicePathData() { - this.createPathLinksObject(); - return this.forwardingPath; - } - - checkFormValidForSubmit():boolean { - if (this.forwardingPath.name && this.isPathValid() ) { - return true; - } - return false; - } - - isPathValid():boolean { - let lastLink = this.links[this.links.length -1] ; - if (lastLink.toNode && lastLink.toCP && lastLink.fromNode && lastLink.fromCP) { - return true; - } - return false; - } -} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.module.ts b/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.module.ts deleted file mode 100644 index 78005317a2..0000000000 --- a/catalog-ui/src/app/ng2/pages/service-path-creator/service-path-creator.module.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { NgModule } from "@angular/core"; -import {CommonModule} from "@angular/common"; -import {ServicePathCreatorComponent} from "./service-path-creator.component"; -import {FormsModule} from "@angular/forms"; -import {FormElementsModule} from "app/ng2/components/ui/form-components/form-elements.module"; -import {UiElementsModule} from "app/ng2/components/ui/ui-elements.module"; -import {LinkRowComponent} from './link-row/link-row.component' -@NgModule({ - declarations: [ - ServicePathCreatorComponent, - LinkRowComponent - ], - imports: [CommonModule, - FormsModule, - FormElementsModule, - UiElementsModule - ], - exports: [], - entryComponents: [ - ServicePathCreatorComponent - ], - providers: [] -}) -export class ServicePathCreatorModule { -} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.html b/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.html deleted file mode 100644 index 33a0090372..0000000000 --- a/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.html +++ /dev/null @@ -1,37 +0,0 @@ - - -
- -
-
-
- {{header}} -
-
-
-
{{path.name}}
-
- - -
-
-
- No flows have been added yet. -
-
- -
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.less b/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.less deleted file mode 100644 index 291119f58c..0000000000 --- a/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.less +++ /dev/null @@ -1,24 +0,0 @@ -@import './../../../../assets/styles/variables.less'; - -.add-path-link { - display: flex; - align-items: flex-end; - flex-direction: column; - padding-bottom: 10px; -} - -.generic-table { - max-height: 233px; -} - -.path-action-buttons { - display: flex; - align-items: center; - justify-content: space-between; - .sprite-new { - cursor: pointer; - } - & > span:only-child { - margin: auto; -} -} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.ts b/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.ts deleted file mode 100644 index 1625ab4b66..0000000000 --- a/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.component.ts +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * ============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========================================================= - */ - -import * as _ from "lodash"; -import {Component, ComponentRef} from '@angular/core'; -import {ForwardingPath} from "app/models/forwarding-path"; -import {ServiceServiceNg2} from "app/ng2/services/component-services/service.service"; -import {ModalService} from "app/ng2/services/modal.service"; -import {ModalComponent} from "app/ng2/components/ui/modal/modal.component"; - -@Component({ - selector: 'service-paths-list', - templateUrl: './service-paths-list.component.html', - styleUrls:['service-paths-list.component.less'], - providers: [ServiceServiceNg2, ModalService] -}) -export default class ServicePathsListComponent { - modalInstance: ComponentRef; - headers: Array = []; - paths: Array = []; - input:any; - onAddServicePath: Function; - onEditServicePath: Function; - isViewOnly: boolean; - - constructor(private serviceService:ServiceServiceNg2) { - this.headers = ['Flow Name','Actions']; - } - - ngOnInit() { - _.forEach(this.input.service.forwardingPaths, (path: ForwardingPath)=> { - this.paths[this.paths.length] = path; - }); - this.paths.sort((a:ForwardingPath, b:ForwardingPath)=> { - return a.name.localeCompare(b.name); - }); - this.onAddServicePath = this.input.onCreateServicePath; - this.onEditServicePath = this.input.onEditServicePath; - this.isViewOnly = this.input.isViewOnly; - } - - deletePath = (id:string):void => { - this.serviceService.deleteServicePath(this.input.service, id).subscribe((res:any) => { - delete this.input.service.forwardingPaths[id]; - this.paths = this.paths.filter(function(path){ - return path.uniqueId !== id; - }); - }); - }; - -} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.module.ts b/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.module.ts deleted file mode 100644 index c236934002..0000000000 --- a/catalog-ui/src/app/ng2/pages/service-paths-list/service-paths-list.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { NgModule } from "@angular/core"; -import {CommonModule} from "@angular/common"; -import ServicePathsListComponent from "./service-paths-list.component"; - -@NgModule({ - declarations: [ - ServicePathsListComponent - ], - imports: [CommonModule], - exports: [], - entryComponents: [ - ServicePathsListComponent - ], - providers: [] -}) -export class ServicePathsListModule { -} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.component.html b/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.component.html new file mode 100644 index 0000000000..d7cf2f930a --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.component.html @@ -0,0 +1,68 @@ + +
+
+ + +
+ + + + + {{row.TIMESTAMP | date }} | {{row.TIMESTAMP | date:"HH:mm O"}} + + + + + {{row.ACTION}} + + + + + {{ row.COMMENT }} + + + + + {{ row.MODIFIER }} + + + + + + + + + + +
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.component.less b/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.component.less new file mode 100644 index 0000000000..4845f4f606 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.component.less @@ -0,0 +1,8 @@ +.sdc-filter-bar-wrapper { + sdc-filter-bar { + flex: 0 0 30%; + } + display: flex; + justify-content: flex-end; + margin-bottom: 10px; +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.component.spec.ts b/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.component.spec.ts new file mode 100644 index 0000000000..25651e0c1f --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.component.spec.ts @@ -0,0 +1,84 @@ +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture } from '@angular/core/testing'; +import { NgxDatatableModule } from '@swimlane/ngx-datatable'; +import { SdcUiServices } from 'onap-ui-angular'; +import 'rxjs/add/observable/of'; +import { Observable } from 'rxjs/Observable'; +import { ConfigureFn, configureTests } from '../../../../../jest/test-config.helper'; +import { ComponentMetadata } from '../../../../models/component-metadata'; +import { ActivityLogService } from '../../../services/activity-log.service'; +import { WorkspaceService } from '../workspace.service'; +import { ActivityLogComponent } from './activity-log.component'; + +describe('activity log component', () => { + + let fixture: ComponentFixture; + let activityLogServiceMock: Partial; + let workspaceServiceMock: Partial; + let loaderServiceMock: Partial; + let componentMetadataMock: ComponentMetadata; + + const mockLogs = '[' + + '{"MODIFIER":"Carlos Santana(m08740)","COMMENT":"comment","STATUS":"200","ACTION":"Checkout","TIMESTAMP":"2018-11-19 13:00:02.388 UTC"},' + + '{"MODIFIER":"John Doe(m08741)","COMMENT":"comment","STATUS":"200","ACTION":"Checkin","TIMESTAMP":"2018-11-20 13:00:02.388 UTC"},' + + '{"MODIFIER":"Jane Doe(m08742)","COMMENT":"comment","STATUS":"200","ACTION":"Checkout","TIMESTAMP":"2018-11-21 13:00:02.388 UTC"}' + + ']'; + + beforeEach( + async(() => { + + componentMetadataMock = new ComponentMetadata(); + componentMetadataMock.uniqueId = 'fake'; + componentMetadataMock.componentType = 'SERVICE'; + + activityLogServiceMock = { + getActivityLog : jest.fn().mockImplementation((type, id) => Observable.of(JSON.parse(mockLogs)) ) + }; + + workspaceServiceMock = { + metadata : componentMetadataMock + }; + + loaderServiceMock = { + activate : jest.fn(), + deactivate: jest.fn() + }; + + const configure: ConfigureFn = (testBed) => { + testBed.configureTestingModule({ + declarations: [ActivityLogComponent], + imports: [NgxDatatableModule], + schemas: [NO_ERRORS_SCHEMA], + providers: [ + { provide: WorkspaceService, useValue: workspaceServiceMock }, + { provide: ActivityLogService, useValue: activityLogServiceMock }, + { provide: SdcUiServices.LoaderService, useValue: loaderServiceMock } + ], + }); + }; + + configureTests(configure).then((testBed) => { + fixture = testBed.createComponent(ActivityLogComponent); + }); + }) + ); + + it('should see exactly 3 activity logs', () => { + fixture.componentInstance.ngOnInit(); + expect(fixture.componentInstance.activities.length).toBe(3); + }); + + it('should filter out 1 element when searching', () => { + fixture.componentInstance.ngOnInit(); + + const event = { + target : { + value : 'Checkin' + } + }; + + expect(fixture.componentInstance.activities.length).toBe(3); + fixture.componentInstance.updateFilter(event); + expect(fixture.componentInstance.activities.length).toBe(1); + }); +}); diff --git a/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.component.ts b/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.component.ts new file mode 100644 index 0000000000..84fb81a1ef --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.component.ts @@ -0,0 +1,48 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { SdcUiServices } from 'onap-ui-angular'; +import { Activity } from '../../../../models/activity'; +import { ActivityLogService } from '../../../services/activity-log.service'; +import { WorkspaceService } from '../workspace.service'; + +@Component({ + selector: 'activity-log', + templateUrl: './activity-log.component.html', + styleUrls: ['./activity-log.component.less', '../../../../../assets/styles/table-style.less'] +}) +export class ActivityLogComponent implements OnInit { + + activities: Activity[] = []; + temp: Activity[] = []; + + constructor(private workspaceService: WorkspaceService, + private activityLogService: ActivityLogService, + private loaderService: SdcUiServices.LoaderService) { + } + + ngOnInit(): void { + this.loaderService.activate(); + const componentId: string = this.workspaceService.metadata.uniqueId; + const componentType: string = this.workspaceService.metadata.componentType; + this.activityLogService.getActivityLog(componentType, componentId).subscribe((logs) => { + this.activities = logs; + this.temp = [...logs]; + this.loaderService.deactivate(); + }, (error) => { this.loaderService.deactivate(); }); + } + + updateFilter(event) { + const val = event.target.value.toLowerCase(); + + // filter our data + const temp = this.temp.filter((activity: Activity) => { + return !val || + activity.COMMENT.toLowerCase().indexOf(val) !== -1 || + activity.STATUS.toLowerCase().indexOf(val) !== -1 || + activity.ACTION.toLowerCase().indexOf(val) !== -1 || + activity.MODIFIER.toLowerCase().indexOf(val) !== -1; + }); + + // update the rows + this.activities = temp; + } +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.module.ts b/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.module.ts new file mode 100644 index 0000000000..39334d8cde --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/activity-log/activity-log.module.ts @@ -0,0 +1,28 @@ +import {CommonModule} from "@angular/common"; +import {NgModule} from "@angular/core"; +import {SdcUiComponentsModule} from "onap-ui-angular"; +import {GlobalPipesModule} from "../../../pipes/global-pipes.module"; +import {ActivityLogComponent} from "./activity-log.component"; +import {ActivityLogService} from "../../../services/activity-log.service"; +import {NgxDatatableModule} from "@swimlane/ngx-datatable"; + +@NgModule({ + declarations: [ + ActivityLogComponent + ], + imports: [ + CommonModule, + SdcUiComponentsModule, + GlobalPipesModule, + NgxDatatableModule + ], + exports: [ + ActivityLogComponent + ], + entryComponents: [ + ActivityLogComponent + ], + providers: [ ActivityLogService ] +}) +export class ActivityLogModule { +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attribute-modal.component.html b/catalog-ui/src/app/ng2/pages/workspace/attributes/attribute-modal.component.html new file mode 100644 index 0000000000..bd30a469e0 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/attributes/attribute-modal.component.html @@ -0,0 +1,104 @@ +
+
+ +
+ +
+ + + + + + +
+ + +
+ + +
+
+ +
+ +
+ + + + + + +
+ + +
+ + + + + + + +
+ + +
+ + + +
+ +
+ + + + + + +
+ + + + +
+
+ +
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attribute-modal.component.ts b/catalog-ui/src/app/ng2/pages/workspace/attributes/attribute-modal.component.ts new file mode 100644 index 0000000000..c703869ad2 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/attributes/attribute-modal.component.ts @@ -0,0 +1,138 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { IDropDownOption } from 'onap-ui-angular/dist/form-elements/dropdown/dropdown-models'; +import { InputComponent } from 'onap-ui-angular/dist/form-elements/text-elements/input/input.component'; +import { Subject } from 'rxjs/Subject'; +import { AttributeModel } from '../../../../models/attributes'; +import { ValidationUtils } from '../../../../utils/validation-utils'; +import { CacheService } from '../../../services/cache.service'; +import { TranslateService } from '../../../shared/translator/translate.service'; +import { AttributeOptions } from './attributes-options'; + +@Component({ + selector: 'attribute-modal', + templateUrl: './attribute-modal.component.html', + styleUrls: ['./attributes.component.less'] +}) +export class AttributeModalComponent implements OnInit { + + @ViewChild('defaultValue') validatedInput: InputComponent; + + public readonly types = AttributeOptions.types; // integer, string, boolean etc. + + public readonly booleanValues = AttributeOptions.booleanValues; // true / false + + public readonly entrySchemaValues = AttributeOptions.entrySchemaValues; // integer, string, boolean, float + + public onValidationChange: Subject = new Subject(); + + public validationPatterns: any; + public readonly listPattern = ValidationUtils.getPropertyListPatterns(); + public readonly mapPattern = ValidationUtils.getPropertyMapPatterns(); + + // The current effective default value pattern + public defaultValuePattern: string; + public defaultValueErrorMessage: string; + + // Attribute being Edited + public attributeToEdit: AttributeModel; + + constructor(private translateService: TranslateService, private cacheService: CacheService) { + this.validationPatterns = this.cacheService.get('validation').validationPatterns; + } + + ngOnInit() { + this.revalidateDefaultValue(); + } + + onHiddenCheckboxClicked(event: boolean) { + this.attributeToEdit.hidden = event; + } + + onTypeSelected(selectedElement: IDropDownOption) { + if (this.attributeToEdit.type !== selectedElement.value && selectedElement.value === 'boolean') { + this.attributeToEdit.defaultValue = ''; // Clean old value in case we choose change type to boolean + } + this.attributeToEdit.type = selectedElement.value; + this.revalidateDefaultValue(); + } + + onBooleanDefaultValueSelected(selectedElement: IDropDownOption) { + if (this.attributeToEdit.type === 'boolean') { + this.attributeToEdit.defaultValue = selectedElement.value; + } + } + + onEntrySchemaTypeSelected(selectedElement: IDropDownOption) { + this.attributeToEdit.schema.property.type = selectedElement.value; + this.revalidateDefaultValue(); + } + + onValidityChange(isValid: boolean, field: string) { + const typeIsValid = this.attributeToEdit.type && this.attributeToEdit.type.length > 0; // Make sure type is defined + + // Make sure name is defined when other fields are changed + let nameIsValid = true; + if (field !== 'name') { + nameIsValid = this.attributeToEdit.name && this.attributeToEdit.name.length > 0; + } + this.onValidationChange.next(isValid && nameIsValid && typeIsValid); + } + + defaultValueChanged() { + this.revalidateDefaultValue(); + } + + /** + * Utility function for UI that converts a simple value to IDropDownOption + * @param val + * @returns {{value: any; label: any}} + */ + toDropDownOption(val: string) { + return { value : val, label: val }; + } + + public isMapUnique = () => { + if (this.attributeToEdit && this.attributeToEdit.type === 'map' && this.attributeToEdit.defaultValue) { + return ValidationUtils.validateUniqueKeys(this.attributeToEdit.defaultValue); + } + return true; + } + + private revalidateDefaultValue() { + this.setDefaultValuePattern(this.attributeToEdit.type); + setTimeout(() => { + if (this.validatedInput) { + this.validatedInput.onKeyPress(this.attributeToEdit.defaultValue); + } }, 250); + } + + private setDefaultValuePattern(valueType: string) { + const selectedSchemaType = this.attributeToEdit.schema.property.type; + this.defaultValuePattern = '.*'; + switch (valueType) { + case 'float': + this.defaultValuePattern = this.validationPatterns.number; + this.defaultValueErrorMessage = this.translateService.translate('VALIDATION_ERROR_TYPE', { type : 'float' }); + break; + case 'integer': + this.defaultValuePattern = this.validationPatterns.integerNoLeadingZero; + this.defaultValueErrorMessage = this.translateService.translate('VALIDATION_ERROR_TYPE', { type : 'integer' }); + break; + case 'list': + if (selectedSchemaType != undefined) { + this.defaultValuePattern = this.listPattern[selectedSchemaType]; + const listTypeStr = `list of ${selectedSchemaType}s (v1, v2, ...) `; + this.defaultValueErrorMessage = this.translateService.translate('VALIDATION_ERROR_TYPE', { type : listTypeStr }); + } + break; + case 'map': + if (selectedSchemaType != undefined) { + this.defaultValuePattern = this.mapPattern[selectedSchemaType]; + const mapTypeStr = `map of ${selectedSchemaType}s (k1:v1, k2:v2, ...)`; + this.defaultValueErrorMessage = this.translateService.translate('VALIDATION_ERROR_TYPE', { type : mapTypeStr }); + } + break; + } + } + +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes-modal.component.spec.ts b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes-modal.component.spec.ts new file mode 100644 index 0000000000..99aa140dd1 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes-modal.component.spec.ts @@ -0,0 +1,128 @@ +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture } from '@angular/core/testing'; +import { ConfigureFn, configureTests } from '../../../../../jest/test-config.helper'; +import { AttributeModel } from '../../../../models/attributes'; +import { ValidationUtils } from '../../../../utils/validation-utils'; +import { CacheService } from '../../../services/cache.service'; +import { TranslatePipe } from '../../../shared/translator/translate.pipe'; +import { TranslateService } from '../../../shared/translator/translate.service'; +import { AttributeModalComponent } from './attribute-modal.component'; + +describe('attributes modal component', () => { + + let fixture: ComponentFixture; + + // Mocks + let translateServiceMock: Partial; + let cacheServiceMock: Partial; + + const validationPatterns = { + integerNoLeadingZero : 'int_regx', + number : 'number_regx' + }; + + const newAttribute = { + uniqueId: '1', name: 'attr1', description: 'description1', type: 'string', hidden: false, defaultValue: 'val1', schema: null + }; + + beforeEach( + async(() => { + + translateServiceMock = { + translate: jest.fn() + }; + + cacheServiceMock = { + get: jest.fn().mockImplementation((k) => { + return { validationPatterns}; + } ) + }; + + const configure: ConfigureFn = (testBed) => { + testBed.configureTestingModule({ + declarations: [AttributeModalComponent, TranslatePipe], + imports: [], + schemas: [NO_ERRORS_SCHEMA], + providers: [ + {provide: TranslateService, useValue: translateServiceMock}, + {provide: CacheService, useValue: cacheServiceMock}, + ] + }); + }; + + configureTests(configure).then((testBed) => { + fixture = testBed.createComponent(AttributeModalComponent); + }); + }) + ); + + it('test that when hidden is clicked, hidden attribute is set', async () => { + fixture.componentInstance.attributeToEdit = new AttributeModel(); + const hidden = fixture.componentInstance.attributeToEdit.hidden; + fixture.componentInstance.ngOnInit(); + + expect(hidden).toBe(false); + fixture.componentInstance.onHiddenCheckboxClicked(true); + expect(fixture.componentInstance.attributeToEdit.hidden).toBe(true); + }); + + it('test that when type is set to boolean default value is cleared', async () => { + const component = fixture.componentInstance; + component.attributeToEdit = new AttributeModel(); + component.ngOnInit(); + + component.onTypeSelected({ value : 'string', label : 'string'}); + component.attributeToEdit.defaultValue = 'some_value'; + component.onTypeSelected({ value : 'boolean', label : 'boolean'}); + expect(component.attributeToEdit.defaultValue).toBe(''); + + component.onBooleanDefaultValueSelected({ value : 'true', label : 'true'}); + expect(component.attributeToEdit.defaultValue).toBe('true'); + }); + + it('test that when certain type is selected, the correct regex pattern is chosen', async () => { + const component = fixture.componentInstance; + component.attributeToEdit = new AttributeModel(); + component.ngOnInit(); + + // integer + component.onTypeSelected({ value : 'integer', label : 'integer'}); + expect(component.defaultValuePattern).toBe(validationPatterns.integerNoLeadingZero); + + // float + component.onTypeSelected({ value : 'float', label : 'float'}); + expect(component.defaultValuePattern).toBe(validationPatterns.number); + + // list is chosen with no schema, regex pattern is set to default + component.onTypeSelected({ value : 'list', label : 'list'}); + expect(component.defaultValuePattern).toEqual('.*'); + + // schema is set to list of int + component.onEntrySchemaTypeSelected({ value : 'integer', label : 'integer' }); + expect(component.defaultValuePattern).toEqual(ValidationUtils.getPropertyListPatterns().integer); + + // schema is set to list of float + component.onEntrySchemaTypeSelected({ value : 'float', label : 'float' }); + expect(component.defaultValuePattern).toEqual(ValidationUtils.getPropertyListPatterns().float); + + // map is selected (float schema is still selected from previous line) + component.onTypeSelected({ value : 'map', label : 'map'}); + expect(component.defaultValuePattern).toEqual(ValidationUtils.getPropertyMapPatterns().float); + + // change schema type to boolean + component.onEntrySchemaTypeSelected({ value : 'boolean', label : 'boolean' }); + }); + + it('should detect map with non-unique keys', async () => { + const component = fixture.componentInstance; + component.attributeToEdit = new AttributeModel(); + component.ngOnInit(); + expect(component.isMapUnique()).toBe(true); // map is not selected so return true by default + component.onTypeSelected({ value : 'map', label : 'map'}); + component.onEntrySchemaTypeSelected({ value : 'boolean', label : 'boolean' }); + component.attributeToEdit.defaultValue = '"1":true,"2":false'; + expect(component.isMapUnique()).toBe(true); + component.attributeToEdit.defaultValue = '"1":true,"1":false'; + expect(component.isMapUnique()).toBe(false); + }); +}); diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes-options.ts b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes-options.ts new file mode 100644 index 0000000000..2a6924bc5e --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes-options.ts @@ -0,0 +1,60 @@ +import { IDropDownOption } from 'onap-ui-angular/dist/form-elements/dropdown/dropdown-models'; + +export class AttributeOptions { + public static readonly types: IDropDownOption[] = [ + { + label: 'integer', + value: 'integer', + }, + { + label: 'string', + value: 'string', + }, + { + label: 'float', + value: 'float' + }, + { + label: 'boolean', + value: 'boolean' + }, + { + label: 'list', + value: 'list' + }, + { + label: 'map', + value: 'map' + } + ]; + + public static readonly booleanValues: IDropDownOption[] = [ + { + label: 'true', + value: 'true', + }, + { + label: 'false', + value: 'false', + } + ]; + + public static readonly entrySchemaValues: IDropDownOption[] = [ + { + label: 'integer', + value: 'integer', + }, + { + label: 'string', + value: 'string', + }, + { + label: 'float', + value: 'float' + }, + { + label: 'boolean', + value: 'boolean' + } + ]; +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.html b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.html new file mode 100644 index 0000000000..00a7a5cec0 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.html @@ -0,0 +1,93 @@ + +
+ +
+ + +
+ + + + + +
{{row.description}}
+
+
+ + + + +
+ + {{ row.name }} +
+
+ +
+ + + + {{row.type}} + + + + + + {{row.defaultValue}} + + + + + +
+ + + + +
+
+
+ +
+
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.less b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.less new file mode 100644 index 0000000000..3e91ae4689 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.less @@ -0,0 +1,36 @@ +.action-bar-wrapper { + flex: 0 0 30%; + display: flex; + justify-content: flex-end; + margin-bottom: 10px; +} + +.add-attr-icon{ + cursor: pointer; +} + +.attr-container { + display: flex; + justify-content: space-between; + + .attr-col { + display: flex; + flex-direction: column; + max-width: 275px; + flex-grow: 1; + } + +} + +.attributeType { + margin-bottom: 10px; +} + +sdc-checkbox { + margin-top: 20px; +} + +.actionColumn { + text-align: center; + padding: 5px; +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.spec.ts b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.spec.ts new file mode 100644 index 0000000000..f676e2b4d9 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.spec.ts @@ -0,0 +1,182 @@ +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture } from '@angular/core/testing'; +import { NgxDatatableModule } from '@swimlane/ngx-datatable'; +import { SdcUiCommon, SdcUiComponents, SdcUiServices } from 'onap-ui-angular'; +import 'rxjs/add/observable/of'; +import { Observable } from 'rxjs/Rx'; +import { ConfigureFn, configureTests } from '../../../../../jest/test-config.helper'; +import { ComponentMetadata } from '../../../../models/component-metadata'; +import { ModalsHandler } from '../../../../utils'; +import { TopologyTemplateService } from '../../../services/component-services/topology-template.service'; +import { TranslateService } from '../../../shared/translator/translate.service'; +import { WorkspaceService } from '../workspace.service'; +import { AttributesComponent } from './attributes.component'; + +describe('attributes component', () => { + + let fixture: ComponentFixture; + + // Mocks + let workspaceServiceMock: Partial; + let topologyTemplateServiceMock: Partial; + let loaderServiceMock: Partial; + let componentMetadataMock: ComponentMetadata; + let modalServiceMock: Partial; + + const mockAttributesList = [ + { uniqueId: '1', name: 'attr1', description: 'description1', type: 'string', hidden: false, defaultValue: 'val1', schema: null }, + { uniqueId : '2', name : 'attr2', description: 'description2', type : 'int', hidden : false, defaultValue : 1, schema : null}, + { uniqueId : '3', name : 'attr3', description: 'description3', type : 'double', hidden : false, defaultValue : 1.0, schema : null}, + { uniqueId : '4', name : 'attr4', description: 'description4', type : 'boolean', hidden : false, defaultValue : true, schema : null}, + ]; + + const newAttribute = { + uniqueId : '5', name : 'attr5', description: 'description5', type : 'string', hidden : false, defaultValue : 'val5', schema : null + }; + const updatedAttribute = { + uniqueId : '2', name : 'attr2', description: 'description_new', type : 'string', hidden : false, defaultValue : 'new_val2', schema : null + }; + const errorAttribute = { + uniqueId : '99', name : 'attr99', description: 'description_error', type : 'string', hidden : false, defaultValue : 'error', schema : null + }; + + beforeEach( + async(() => { + + componentMetadataMock = new ComponentMetadata(); + componentMetadataMock.uniqueId = 'fake'; + componentMetadataMock.componentType = 'VL'; + + topologyTemplateServiceMock = { + getComponentAttributes: jest.fn().mockResolvedValue({ attributes : mockAttributesList }), + addAttributeAsync: jest.fn().mockImplementation( + (compType, cUid, attr) => { + if (attr === errorAttribute) { + return Observable.throwError('add_error').toPromise(); + } else { + return Observable.of(newAttribute).toPromise(); + } + } + ), + updateAttributeAsync: jest.fn().mockImplementation( + (compType, cUid, attr) => { + if (attr === errorAttribute) { + return Observable.throwError('update_error').toPromise(); + } else { + return Observable.of(updatedAttribute).toPromise(); + } + } + ), + deleteAttributeAsync: jest.fn().mockImplementation((cid, ctype, attr) => Observable.of(attr)) + }; + + workspaceServiceMock = { + metadata: componentMetadataMock + }; + + const customModalInstance = { innerModalContent: { instance: { onValidationChange: { subscribe: jest.fn()}}}}; + + modalServiceMock = { + openInfoModal: jest.fn(), + openCustomModal: jest.fn().mockImplementation(() => customModalInstance) + }; + + loaderServiceMock = { + activate: jest.fn(), + deactivate: jest.fn() + }; + + const configure: ConfigureFn = (testBed) => { + testBed.configureTestingModule({ + declarations: [AttributesComponent], + imports: [NgxDatatableModule], + schemas: [NO_ERRORS_SCHEMA], + providers: [ + {provide: WorkspaceService, useValue: workspaceServiceMock}, + {provide: TopologyTemplateService, useValue: topologyTemplateServiceMock}, + {provide: ModalsHandler, useValue: {}}, + {provide: TranslateService, useValue: { translate: jest.fn() }}, + {provide: SdcUiServices.ModalService, useValue: modalServiceMock }, + {provide: SdcUiServices.LoaderService, useValue: loaderServiceMock } + ], + }); + }; + + configureTests(configure).then((testBed) => { + fixture = testBed.createComponent(AttributesComponent); + }); + }) + ); + + it('should see exactly 1 attributes on init', async () => { + await fixture.componentInstance.asyncInitComponent(); + expect(fixture.componentInstance.getAttributes().length).toEqual(4); + }); + + it('should see exactly 5 attributes when adding', async () => { + await fixture.componentInstance.asyncInitComponent(); + expect(fixture.componentInstance.getAttributes().length).toEqual(4); + + await fixture.componentInstance.addOrUpdateAttribute(newAttribute, false); + expect(fixture.componentInstance.getAttributes().length).toEqual(5); + }); + + it('should see exactly 3 attributes when deleting', async () => { + await fixture.componentInstance.asyncInitComponent(); + expect(fixture.componentInstance.getAttributes().length).toEqual(4); + const attrToDelete = mockAttributesList[0]; + expect(fixture.componentInstance.getAttributes().filter((attr) => attr.uniqueId === attrToDelete.uniqueId).length).toEqual(1); + await fixture.componentInstance.deleteAttribute(attrToDelete); + expect(fixture.componentInstance.getAttributes().length).toEqual(3); + expect(fixture.componentInstance.getAttributes().filter((attr) => attr.uniqueId === attrToDelete.uniqueId).length).toEqual(0); + }); + + it('should see updated attribute', async () => { + await fixture.componentInstance.asyncInitComponent(); + + await fixture.componentInstance.addOrUpdateAttribute(updatedAttribute, true); + expect(fixture.componentInstance.getAttributes().length).toEqual(4); + const attribute = fixture.componentInstance.getAttributes().filter( (attr) => { + return attr.uniqueId === updatedAttribute.uniqueId; + })[0]; + expect(attribute.description).toEqual( 'description_new'); + }); + + it('Add fails, make sure loader is deactivated and attribute is not added', async () => { + await fixture.componentInstance.asyncInitComponent(); + const numAttributes = fixture.componentInstance.getAttributes().length; + await fixture.componentInstance.addOrUpdateAttribute(errorAttribute, false); // Add + expect(loaderServiceMock.deactivate).toHaveBeenCalled(); + expect(fixture.componentInstance.getAttributes().length).toEqual(numAttributes); + }); + + it('Update fails, make sure loader is deactivated', async () => { + await fixture.componentInstance.asyncInitComponent(); + const numAttributes = fixture.componentInstance.getAttributes().length; + await fixture.componentInstance.addOrUpdateAttribute(errorAttribute, true); // Add + expect(loaderServiceMock.deactivate).toHaveBeenCalled(); + expect(fixture.componentInstance.getAttributes().length).toEqual(numAttributes); + }); + + it('on delete modal shell be opened', async () => { + await fixture.componentInstance.asyncInitComponent(); + const event = { stopPropagation: jest.fn() }; + fixture.componentInstance.onDeleteAttribute(event, fixture.componentInstance.getAttributes()[0]); + expect(event.stopPropagation).toHaveBeenCalled(); + expect(modalServiceMock.openInfoModal).toHaveBeenCalled(); + }); + + it('on add modal shell be opened', async () => { + await fixture.componentInstance.asyncInitComponent(); + fixture.componentInstance.onAddAttribute(); + expect(modalServiceMock.openCustomModal).toHaveBeenCalled(); + }); + + it('on edit modal shell be opened', async () => { + await fixture.componentInstance.asyncInitComponent(); + const event = { stopPropagation: jest.fn() }; + fixture.componentInstance.onEditAttribute(event, fixture.componentInstance.getAttributes()[0]); + expect(event.stopPropagation).toHaveBeenCalled(); + expect(modalServiceMock.openCustomModal).toHaveBeenCalled(); + }); +}); diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.ts b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.ts new file mode 100644 index 0000000000..bc47f1456b --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.component.ts @@ -0,0 +1,188 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { Select } from '@ngxs/store'; +import { IAttributeModel } from 'app/models'; +import * as _ from 'lodash'; +import { SdcUiCommon, SdcUiComponents, SdcUiServices } from 'onap-ui-angular'; +import { ModalComponent } from 'onap-ui-angular/dist/modals/modal.component'; +import { AttributeModel } from '../../../../models'; +import { Resource } from '../../../../models'; +import { ModalsHandler } from '../../../../utils'; +import { TopologyTemplateService } from '../../../services/component-services/topology-template.service'; +import { TranslateService } from '../../../shared/translator/translate.service'; +import { WorkspaceState } from '../../../store/states/workspace.state'; +import { WorkspaceService } from '../workspace.service'; +import { AttributeModalComponent } from './attribute-modal.component'; + +@Component({ + selector: 'attributes', + templateUrl: './attributes.component.html', + styleUrls: ['./attributes.component.less', '../../../../../assets/styles/table-style.less'] +}) +export class AttributesComponent implements OnInit { + + @Select(WorkspaceState.isViewOnly) + isViewOnly$: boolean; + + @ViewChild('componentAttributesTable') + private table: any; + + private componentType: string; + private componentUid: string; + + private attributes: IAttributeModel[] = []; + private temp: IAttributeModel[] = []; + private customModalInstance: ModalComponent; + + constructor(private workspaceService: WorkspaceService, + private topologyTemplateService: TopologyTemplateService, + private modalsHandler: ModalsHandler, + private modalService: SdcUiServices.ModalService, + private loaderService: SdcUiServices.LoaderService, + private translateService: TranslateService) { + + this.componentType = this.workspaceService.metadata.componentType; + this.componentUid = this.workspaceService.metadata.uniqueId; + } + + ngOnInit(): void { + this.asyncInitComponent(); + } + + async asyncInitComponent() { + this.loaderService.activate(); + const response = await this.topologyTemplateService.getComponentAttributes(this.componentType, this.componentUid); + this.attributes = response.attributes; + this.temp = [...response.attributes]; + this.loaderService.deactivate(); + } + + getAttributes(): IAttributeModel[] { + return this.attributes; + } + + addOrUpdateAttribute = async (attribute: AttributeModel, isEdit: boolean) => { + this.loaderService.activate(); + let attributeFromServer: AttributeModel; + this.temp = [...this.attributes]; + + const deactivateLoader = () => { + this.loaderService.deactivate(); + return undefined; + }; + + if (isEdit) { + attributeFromServer = await this.topologyTemplateService + .updateAttributeAsync(this.componentType, this.componentUid, attribute) + .catch(deactivateLoader); + if (attributeFromServer) { + const indexOfUpdatedAttribute = _.findIndex(this.temp, (e) => e.uniqueId === attributeFromServer.uniqueId); + this.temp[indexOfUpdatedAttribute] = attributeFromServer; + } + } else { + attributeFromServer = await this.topologyTemplateService + .addAttributeAsync(this.componentType, this.componentUid, attribute) + .catch(deactivateLoader); + if (attributeFromServer) { + this.temp.push(attributeFromServer); + } + } + this.attributes = this.temp; + this.loaderService.deactivate(); + } + + deleteAttribute = async (attributeToDelete: AttributeModel) => { + this.loaderService.activate(); + this.temp = [...this.attributes]; + const res = await this.topologyTemplateService.deleteAttributeAsync(this.componentType, this.componentUid, attributeToDelete); + _.remove(this.temp, (attr) => attr.uniqueId === attributeToDelete.uniqueId); + this.attributes = this.temp; + this.loaderService.deactivate(); + }; + + openAddEditModal(selectedRow: AttributeModel, isEdit: boolean) { + const component = new Resource(undefined, undefined, undefined); + component.componentType = this.componentType; + component.uniqueId = this.componentUid; + + const title: string = this.translateService.translate('ATTRIBUTE_DETAILS_MODAL_TITLE'); + const attributeModalConfig = { + title, + size: 'md', + type: SdcUiCommon.ModalType.custom, + buttons: [ + { + id: 'save', + text: 'Save', + // spinner_position: Placement.left, + size: 'sm', + callback: () => this.modalCallBack(isEdit), + closeModal: true, + disabled: false, + } + ] as SdcUiCommon.IModalButtonComponent[] + }; + + this.customModalInstance = this.modalService.openCustomModal(attributeModalConfig, AttributeModalComponent, { attributeToEdit: selectedRow }); + this.customModalInstance.innerModalContent.instance. + onValidationChange.subscribe((isValid) => this.customModalInstance.getButtonById('save').disabled = !isValid); + } + + /*********************** + * Call Backs from UI * + ***********************/ + + /** + * Called when 'Add' is clicked + */ + onAddAttribute() { + this.openAddEditModal(new AttributeModel(), false); + } + + /** + * Called when 'Edit' button is clicked + */ + onEditAttribute(event, row) { + event.stopPropagation(); + + const attributeToEdit: AttributeModel = new AttributeModel(row); + this.openAddEditModal(attributeToEdit, true); + } + + /** + * Called when 'Delete' button is clicked + */ + onDeleteAttribute(event, row: AttributeModel) { + event.stopPropagation(); + const onOk = () => { + this.deleteAttribute(row); + }; + + const title: string = this.translateService.translate('ATTRIBUTE_VIEW_DELETE_MODAL_TITLE'); + const message: string = this.translateService.translate('ATTRIBUTE_VIEW_DELETE_MODAL_TEXT'); + const okButton = new SdcUiComponents.ModalButtonComponent(); + okButton.testId = 'OK'; + okButton.text = 'OK'; + okButton.type = SdcUiCommon.ButtonType.info; + okButton.closeModal = true; + okButton.callback = onOk; + + this.modalService.openInfoModal(title, message, 'delete-modal', [okButton]); + } + + onExpandRow(event) { + if (event.type === 'click') { + this.table.rowDetail.toggleExpandRow(event.row); + } + } + + /** + * Callback from Modal after "Save" is clicked + * + * @param {boolean} isEdit - Whether modal is edit or add attribute + */ + modalCallBack = (isEdit: boolean) => { + const attribute: AttributeModel = this.customModalInstance.innerModalContent.instance.attributeToEdit; + this.addOrUpdateAttribute(attribute, isEdit); + } + +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.module.ts b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.module.ts new file mode 100644 index 0000000000..5abb952e37 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/attributes/attributes.module.ts @@ -0,0 +1,32 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { SdcUiComponentsModule } from 'onap-ui-angular'; +import { GlobalPipesModule } from '../../../pipes/global-pipes.module'; +import { AttributesComponent } from './attributes.component'; +import { NgxDatatableModule } from '@swimlane/ngx-datatable'; +import { TopologyTemplateService } from '../../../services/component-services/topology-template.service'; +import { AttributeModalComponent } from './attribute-modal.component'; +import { TranslateModule } from '../../../shared/translator/translate.module'; + +@NgModule({ + declarations: [ + AttributesComponent, + AttributeModalComponent + ], + imports: [ + CommonModule, + SdcUiComponentsModule, + GlobalPipesModule, + NgxDatatableModule, + TranslateModule + ], + exports: [ + AttributesComponent + ], + entryComponents: [ + AttributesComponent, AttributeModalComponent + ], + providers: [TopologyTemplateService] +}) +export class AttributesModule { +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/__snapshots__/deployment-artifacts-page.spec.ts.snap b/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/__snapshots__/deployment-artifacts-page.spec.ts.snap new file mode 100644 index 0000000000..b53674497c --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/__snapshots__/deployment-artifacts-page.spec.ts.snap @@ -0,0 +1,24 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`deployment artifacts page should match current snapshot of informational artifact pages component 1`] = ` + + + +`; diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.component.html b/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.component.html new file mode 100644 index 0000000000..35592d846a --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.component.html @@ -0,0 +1,73 @@ +
+ + + + +
+
+
+ {{row.artifactDisplayName}} + + + +
+
+ + + {{row.artifactType}} + + exactly 2 tosca artifacts + + + {{ row.artifactVersion }} + + + + + {{ row.artifactUUID }} + + + + +
+ + + + + + +
+
+
+ + + + + + +
+
diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.component.less b/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.component.less new file mode 100644 index 0000000000..22ceb96653 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.component.less @@ -0,0 +1,55 @@ +.deployment-artifact-page { + + + .env-artifact-container { + margin-left: -25px; + margin-top: -21px; + padding-left: 10px; + position: absolute; + background-color: white; + .env-artifact { + border-left: 1px #848586 solid; + height: 33px; + + border-top: 1px #848586 solid; + border-bottom: 1px #848586 solid; + width: 10px; + float: left; + + } + } + .add-artifact-btn { + display: flex; + cursor: pointer; + justify-content: flex-end; + margin-bottom: 10px; + } + .download-artifact-button { + display: flex; + justify-content: center; + + .action-icon { + margin-right: 10px; + } + } + + .table-footer-container { + display: flex; + align-items: center; + width: 100%; + justify-content: center; + margin: 20px 0px; + } +} + +:host ::ng-deep { + + .ngx-datatable { + //border: 1px solid red; + .datatable-body-cell { + .info { + float: right; + } + } + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.component.ts b/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.component.ts new file mode 100644 index 0000000000..53b21b34b6 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.component.ts @@ -0,0 +1,155 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { Select, Store } from '@ngxs/store'; +import { ArtifactModel } from 'app/models'; +import * as _ from 'lodash'; +import { SdcUiCommon, SdcUiComponents, SdcUiServices } from 'onap-ui-angular'; +import { Observable } from 'rxjs/index'; +import { map } from 'rxjs/operators'; +import { GabConfig } from '../../../../models/gab-config'; +import { PathsAndNamesDefinition } from '../../../../models/paths-and-names'; +import { GenericArtifactBrowserComponent } from '../../../../ng2/components/logic/generic-artifact-browser/generic-artifact-browser.component'; +import { ArtifactGroupType, ArtifactType } from '../../../../utils/constants'; +import { ArtifactsService } from '../../../components/forms/artifacts-form/artifacts.service'; +import { PopoverContentComponent } from '../../../components/ui/popover/popover-content.component'; +import { CacheService } from '../../../services/cache.service'; +import { TranslateService } from '../../../shared/translator/translate.service'; +import { GetArtifactsByTypeAction } from '../../../store/actions/artifacts.action'; +import { ArtifactsState } from '../../../store/states/artifacts.state'; +import { WorkspaceState, WorkspaceStateModel } from '../../../store/states/workspace.state'; +import { WorkspaceService } from '../workspace.service'; +import { ModalService } from 'app/ng2/services/modal.service'; + +export interface IPoint { + x: number; + y: number; +} + +@Component({ + selector: 'deployment-artifact-page', + templateUrl: './deployment-artifacts-page.component.html', + styleUrls: ['./deployment-artifacts-page.component.less', '../../../../../assets/styles/table-style.less'] +}) +export class DeploymentArtifactsPageComponent implements OnInit { + + public componentId: string; + public componentType: string; + public deploymentArtifacts$: Observable; + public isComponentInstanceSelected: boolean; + + @Select(WorkspaceState) workspaceState$: Observable; + @ViewChild('informationArtifactsTable') table: any; + @ViewChild('popoverForm') popoverContentComponent: PopoverContentComponent; + + constructor(private workspaceService: WorkspaceService, + private artifactsService: ArtifactsService, + private store: Store, + private popoverService: SdcUiServices.PopoverService, + private cacheService: CacheService, + private modalService: SdcUiServices.ModalService, + private translateService: TranslateService) { + } + + private getEnvArtifact = (heatArtifact: ArtifactModel, artifacts: ArtifactModel[]): ArtifactModel => { + return _.find(artifacts, (item: ArtifactModel) => { + return item.generatedFromId === heatArtifact.uniqueId; + }); + }; + + // we need to sort the artifact in a way that the env artifact is always under the artifact he is connected to- this is cause of the way the ngx databale work + private sortArtifacts = ((artifacts) => { + const sortedArtifacts = []; + _.forEach(artifacts, (artifact: ArtifactModel): void => { + const envArtifact = this.getEnvArtifact(artifact, artifacts); + if (!artifact.generatedFromId) { + sortedArtifacts.push(artifact); + } + if (envArtifact) { + sortedArtifacts.push(envArtifact); + } + }); + return sortedArtifacts; + }) + + ngOnInit(): void { + this.componentId = this.workspaceService.metadata.uniqueId; + this.componentType = this.workspaceService.metadata.componentType; + + this.store.dispatch(new GetArtifactsByTypeAction({ + componentType: this.componentType, + componentId: this.componentId, + artifactType: ArtifactGroupType.DEPLOYMENT + })); + this.deploymentArtifacts$ = this.store.select(ArtifactsState.getArtifactsByType).pipe(map((filterFn) => filterFn(ArtifactType.DEPLOYMENT))).pipe(map(artifacts => { + return this.sortArtifacts(artifacts); + })); + } + + onActivate(event) { + if (event.type === 'click') { + this.table.rowDetail.toggleExpandRow(event.row); + } + } + + public addOrUpdateArtifact = (artifact: ArtifactModel, isViewOnly: boolean) => { + this.artifactsService.openArtifactModal(this.componentId, this.componentType, artifact, ArtifactGroupType.DEPLOYMENT, isViewOnly); + } + + public deleteArtifact = (artifactToDelete) => { + this.artifactsService.deleteArtifact(this.componentType, this.componentId, artifactToDelete); + } + + private openPopOver = (title: string, content: string, positionOnPage: IPoint, location: string) => { + this.popoverService.createPopOver(title, content, positionOnPage, location); + } + + public updateEnvParams = (artifact: ArtifactModel, isViewOnly: boolean) => { + this.artifactsService.openUpdateEnvParams(this.componentType, this.componentId, artifact ); + } + + private openGenericArtifactBrowserModal = (artifact: ArtifactModel): void => { + const titleStr = 'Generic Artifact Browser'; + const modalConfig = { + size: 'sdc-xl', + title: titleStr, + type: SdcUiCommon.ModalType.custom, + buttons: [{ + id: 'closeGABButton', + text: 'Close', + size: 'sm', + closeModal: true + }] as SdcUiCommon.IModalButtonComponent[] + }; + + const uiConfiguration: any = this.cacheService.get('UIConfiguration'); + let noConfig: boolean = false; + let pathsandnamesArr: PathsAndNamesDefinition[] = []; + + if (typeof uiConfiguration.gab === 'undefined') { + noConfig = true; + } else { + const gabConfig: GabConfig = uiConfiguration.gab + .find((config) => config.artifactType === artifact.artifactType); + if (typeof gabConfig === 'undefined') { + noConfig = true; + } else { + pathsandnamesArr = gabConfig.pathsAndNamesDefinitions; + } + } + + + if (noConfig) { + const msg = this.translateService.translate('DEPLOYMENT_ARTIFACT_GAB_NO_CONFIG'); + this.modalService.openAlertModal(titleStr, msg); + } + + const modalInputs = { + pathsandnames: pathsandnamesArr, + artifactid: artifact.esId, + resourceid: this.componentId + }; + + this.modalService.openCustomModal(modalConfig, GenericArtifactBrowserComponent, modalInputs); + + } + +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.module.ts b/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.module.ts new file mode 100644 index 0000000000..398e9d3f4d --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.module.ts @@ -0,0 +1,35 @@ +import {CommonModule} from "@angular/common"; +import {NgModule} from "@angular/core"; +import {SdcUiComponentsModule} from "onap-ui-angular"; +import {NgxDatatableModule} from "@swimlane/ngx-datatable"; +import {UiElementsModule} from "../../../components/ui/ui-elements.module"; +import {ArtifactFormModule} from "../../../components/forms/artifacts-form/artifact-form.module"; +import {ArtifactsService} from "../../../components/forms/artifacts-form/artifacts.service"; +import {DeploymentArtifactsPageComponent} from "./deployment-artifacts-page.component"; +import {TranslatePipe} from "../../../shared/translator/translate.pipe"; +import {TranslateModule} from "../../../shared/translator/translate.module"; +import {GenericArtifactBrowserModule} from "../../../components/logic/generic-artifact-browser/generic-artifact-browser.module"; + +@NgModule({ + declarations: [ + DeploymentArtifactsPageComponent + ], + imports: [ + TranslateModule, + CommonModule, + SdcUiComponentsModule, + NgxDatatableModule, + UiElementsModule, + ArtifactFormModule, + GenericArtifactBrowserModule + ], + exports: [ + DeploymentArtifactsPageComponent + ], + entryComponents: [ + DeploymentArtifactsPageComponent + ], + providers:[ArtifactsService] +}) +export class DeploymentArtifactsPageModule { +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.spec.ts b/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.spec.ts new file mode 100644 index 0000000000..056efdc5d4 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment-artifacts/deployment-artifacts-page.spec.ts @@ -0,0 +1,86 @@ +// import ' rxjs/add/observable/of'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, ComponentFixture } from '@angular/core/testing'; +import { NgxsModule, Store } from '@ngxs/store'; +import { NgxDatatableModule } from '@swimlane/ngx-datatable'; +import { SdcUiServices } from 'onap-ui-angular'; +import { Observable } from 'rxjs/Observable'; +import { deploymentArtifactMock } from '../../../../../jest/mocks/artifacts-mock'; +import { ConfigureFn, configureTests } from '../../../../../jest/test-config.helper'; +import { ComponentMetadata } from '../../../../models/component-metadata'; +import { ArtifactsService } from '../../../components/forms/artifacts-form/artifacts.service'; +import { CacheService } from '../../../services/cache.service'; +import { TopologyTemplateService } from '../../../services/component-services/topology-template.service'; +import { TranslateModule } from '../../../shared/translator/translate.module'; +import { TranslateService } from '../../../shared/translator/translate.service'; +import { ArtifactsState } from '../../../store/states/artifacts.state'; +import { WorkspaceService } from '../workspace.service'; +import { DeploymentArtifactsPageComponent } from './deployment-artifacts-page.component'; +import {ModalService} from "../../../services/modal.service"; + +describe('deployment artifacts page', () => { + + let fixture: ComponentFixture; + let topologyTemplateServiceMock: Partial; + let workspaceServiceMock: Partial; + let loaderServiceMock: Partial; + let store: Store; + + beforeEach( + async(() => { + + topologyTemplateServiceMock = { + getArtifactsByType: jest.fn().mockImplementation((componentType, id, artifactType) => Observable.of(deploymentArtifactMock)) + }; + workspaceServiceMock = { + metadata: { + uniqueId: 'service_unique_id', + componentType: 'SERVICE' + } + } + + loaderServiceMock = { + activate: jest.fn(), + deactivate: jest.fn() + } + const configure: ConfigureFn = (testBed) => { + testBed.configureTestingModule({ + declarations: [DeploymentArtifactsPageComponent], + imports: [NgxDatatableModule, TranslateModule, NgxsModule.forRoot([ArtifactsState])], + schemas: [NO_ERRORS_SCHEMA], + providers: [ + {provide: WorkspaceService, useValue: workspaceServiceMock}, + {provide: TopologyTemplateService, useValue: topologyTemplateServiceMock}, + {provide: SdcUiServices.LoaderService, useValue: loaderServiceMock}, + {provide: ArtifactsService, useValue: {}}, + {provide: SdcUiServices.PopoverService, useValue: {}}, + {provide: CacheService, useValue: {}}, + {provide: SdcUiServices.ModalService, useValue: {}}, + {provide: ModalService, useValue: {}}, + {provide: TranslateService, useValue: {}} + ], + }); + }; + + configureTests(configure).then((testBed) => { + fixture = testBed.createComponent(DeploymentArtifactsPageComponent); + store = testBed.get(Store); + }); + }) + ); + + it('should match current snapshot of informational artifact pages component', () => { + expect(fixture).toMatchSnapshot(); + }); + + it('should see exactly 2 tosca artifacts', () => { + fixture.componentInstance.ngOnInit(); + fixture.componentInstance.deploymentArtifacts$.subscribe((artifacts) => { + expect(artifacts.length).toEqual(8); + }) + store.selectOnce((state) => state.artifacts.deploymentArtifacts).subscribe((artifacts) => { + expect(artifacts.length).toEqual(8); + }); + }); + +}); diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment/deployment-page.component.html b/catalog-ui/src/app/ng2/pages/workspace/deployment/deployment-page.component.html new file mode 100644 index 0000000000..885277217d --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment/deployment-page.component.html @@ -0,0 +1,11 @@ +
+ + + + + + + + +
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment/deployment-page.component.less b/catalog-ui/src/app/ng2/pages/workspace/deployment/deployment-page.component.less new file mode 100644 index 0000000000..4b7a1e7e9f --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment/deployment-page.component.less @@ -0,0 +1,24 @@ +@import './../../../../../assets/styles/variables.less'; +@import './../../../../../assets/styles/override.less'; +.deployment-page { + width: 100%; + height: 100%; + + /deep/ .sdc-tabs { + height: 100%; + } + /deep/ .sdc-tabs-list { + position: absolute; + top: 22px; + right: 303px; + background-color: @sdcui_color_silver; + + svg-icon-label { + vertical-align: middle; + } + } + /deep/ .sdc-tab-content { + height: 100%; + } +} + diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment/deployment-page.component.ts b/catalog-ui/src/app/ng2/pages/workspace/deployment/deployment-page.component.ts new file mode 100644 index 0000000000..12bd5369c7 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment/deployment-page.component.ts @@ -0,0 +1,78 @@ +/*- + * ============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========================================================= + */ + +import {Component} from "@angular/core"; +import {HierarchyTabComponent} from "./panel/panel-tabs/hierarchy-tab/hierarchy-tab.component"; +import {ComponentGenericResponse} from "../../../services/responses/component-generic-response"; +import {TopologyTemplateService} from "../../../services/component-services/topology-template.service"; +import {WorkspaceService} from "../workspace.service"; +import {Module} from "app/models"; +import {SdcUiServices} from "onap-ui-angular"; +import {Select} from "@ngxs/store"; +import {WorkspaceState} from "../../../store/states/workspace.state"; +import {DeploymentGraphService} from "../../composition/deployment/deployment-graph.service"; + +const tabs = + { + hierarchyTab: { + titleIcon: 'composition-o', + component: HierarchyTabComponent, + input: {}, + isActive: true, + tooltipText: 'Hierarchy' + } + }; + +@Component({ + selector: 'deployment-page', + templateUrl: './deployment-page.component.html', + styleUrls: ['deployment-page.component.less'] +}) + +export class DeploymentPageComponent { + public tabs: Array; + public resourceType: string; + public modules: Array; + public isDataAvailable: boolean; + + @Select(WorkspaceState.isViewOnly) isViewOnly$: boolean; + + constructor(private topologyTemplateService: TopologyTemplateService, + private workspaceService: WorkspaceService, + private deploymentService: DeploymentGraphService, + private loaderService: SdcUiServices.LoaderService) { + this.tabs = []; + this.isDataAvailable = false; + } + + ngOnInit(): void { + this.topologyTemplateService.getDeploymentGraphData(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId).subscribe((response: ComponentGenericResponse) => { + this.deploymentService.componentInstances = response.componentInstances; + this.deploymentService.componentInstancesRelations = response.componentInstancesRelations; + this.deploymentService.modules = response.modules; + this.isDataAvailable = true; + this.loaderService.deactivate(); + }); + + this.loaderService.activate(); + this.resourceType = this.workspaceService.getMetadataType(); + this.tabs.push(tabs.hierarchyTab); + } +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment/deployment-page.module.ts b/catalog-ui/src/app/ng2/pages/workspace/deployment/deployment-page.module.ts new file mode 100644 index 0000000000..3635e8f2cf --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment/deployment-page.module.ts @@ -0,0 +1,30 @@ +/** + * Created by ob0695 on 6/4/2018. + */ +import {NgModule} from "@angular/core"; +import {CommonModule} from "@angular/common"; +import {DeploymentPageComponent} from "./deployment-page.component"; +import {SdcUiComponentsModule} from "onap-ui-angular"; +import {UiElementsModule} from "../../../components/ui/ui-elements.module"; +import {TranslateModule} from "../../../shared/translator/translate.module"; +import {GlobalPipesModule} from "../../../pipes/global-pipes.module"; +import {HierarchyTabModule} from "./panel/panel-tabs/hierarchy-tab/hierarchy-tab.module"; +import {DeploymentGraphService} from "../../composition/deployment/deployment-graph.service"; +import {DeploymentGraphModule} from "../../composition/deployment/deployment-graph.module"; + +@NgModule({ + declarations: [DeploymentPageComponent], + imports: [CommonModule, + DeploymentGraphModule, + SdcUiComponentsModule, + UiElementsModule, + TranslateModule, + GlobalPipesModule, + HierarchyTabModule + ], + exports: [DeploymentPageComponent], + entryComponents: [DeploymentPageComponent], + providers: [DeploymentGraphService] +}) +export class DeploymentPageModule { +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/edit-module-name/edit-module-name.component.html b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/edit-module-name/edit-module-name.component.html new file mode 100644 index 0000000000..d5b9d9e9b2 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/edit-module-name/edit-module-name.component.html @@ -0,0 +1,29 @@ +
+
{{selectModule.vfInstanceName}}
+
+ + + + + +
+
{{selectModule.moduleName}}
+ + + + +
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/edit-module-name/edit-module-name.component.less b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/edit-module-name/edit-module-name.component.less new file mode 100644 index 0000000000..721ad53bc3 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/edit-module-name/edit-module-name.component.less @@ -0,0 +1,20 @@ +.edit-module-name-btn{ + float:right; + margin-left: 10px; + margin-bottom: 20px; +} +.save-button { + margin-left: 30px; +} +.cancel-button { + margin-left: 20px; +} +.edit-module-name-heatName { + margin-bottom: 15px; +} +.edit-module-name-label { + text-overflow: ellipsis; + display: block; + white-space: nowrap; + margin-bottom: 10px; +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/edit-module-name/edit-module-name.component.ts b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/edit-module-name/edit-module-name.component.ts new file mode 100644 index 0000000000..819182c75f --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/edit-module-name/edit-module-name.component.ts @@ -0,0 +1,24 @@ +import { Component, Input, Output, OnInit } from "@angular/core"; +import { EventEmitter } from "@angular/core"; +import { DisplayModule } from "../../../../../../../models/modules/base-module"; +import { ValidationConfiguration } from "../../../../../../../models/validation-config"; + +@Component({ + selector: 'edit-module-name', + templateUrl: './edit-module-name.component.html', + styleUrls: ['edit-module-name.component.less'] +}) +export class EditModuleName implements OnInit{ + @Input() selectModule:DisplayModule; + @Output() clickButtonEvent: EventEmitter = new EventEmitter(); + private pattern = ValidationConfiguration.validation.validationPatterns.stringOrEmpty; + private originalName: string; + constructor(){} + public ngOnInit(): void { + this.originalName = this.selectModule.heatName; + } + + private clickButton(saveOrCancel: boolean) : void { + this.clickButtonEvent.emit(saveOrCancel ? this.selectModule.heatName : null); + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.component.html b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.component.html new file mode 100644 index 0000000000..7c0e60b814 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.component.html @@ -0,0 +1,119 @@ +
+ +
{{'DEPLOYMENT_TAB_TITLE' | translate }}
+
+
+
+
{{topologyTemplateName}}
+
+ +
+
{{memberId}}
+
+
+
+
+
+ + +
+
+ +
+ +
+
{{memberId}}
+
+
+
+
+
+
+
+ + +
+
+
+
{{selectedModule.name}}
+
+ +
+
+
+
Module ID:
+
{{selectedModule.groupUUID}}
+
+
+
Customization ID:
+
{{selectedModule.customizationUUID}}
+
+
+
Invariant UUID:
+
{{selectedModule.invariantUUID}}
+
+
+
Version:
+
{{selectedModule.version}}
+
+
+
IsBase:
+
{{selectedModule.isBase}}
+
+ +
+ +
+
+
+ {{property.name}} +
+
Type: {{property.type}}
+
+ Value: {{property.value}}
+
+
+
+ +
+
+
+
{{artifact.artifactName}}
+
UUID: {{artifact.artifactUUID}}
+
+ Version: {{artifact.artifactVersion}}
+
+
+
+
+
+
+
diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.component.less b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.component.less new file mode 100644 index 0000000000..269ca0aee0 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.component.less @@ -0,0 +1,222 @@ +@import './../../../../../../../../assets/styles/variables.less'; +.sdc-hierarchy-tab { + padding: 15px 0 0 0; + background-color: #f8f8f8; + height: 100%; + box-shadow: 0.3px 1px 3px rgba(24, 24, 25, 0.42); + display: flex; + flex-flow: column; + + .sdc-hierarchy-tab-title { + color: @main_color_a; + padding: 0 0 15px 20px; + border-bottom: 1px solid #d2d2d2; + } + + .sdc-hierarchy-tab-sub-title { + color: @main_color_a; + padding: 15px 20px 15px 20px; + } + + .scroll-module-list { + overflow-y: auto; + display: flex; + height: 100%; + flex-direction: column; + } + + /deep/ .expand-collapse-container { + margin-bottom: 0; + + .sdc-accordion-header { + white-space: nowrap; + line-height: 22px; + background-color: @tlv_color_u; + padding: 8px 20px 8px 8px; + box-shadow: inset 0px -1px 0px 0px rgba(255, 255, 255, 0.7); + height: 40px; + + .title { + overflow: hidden; + text-overflow: ellipsis; + max-width: 215px; + } + } + + .sdc-accordion-body.open { + padding: 0 0 5px 0; + } + + .sdc-accordion-header:hover { + background-color: @main_color_o; + } + + &.outer-container { + .sdc-accordion-body { + padding-left: 0; + } + } + + &.inner-container { + margin-bottom: 0; + + .sdc-accordion-header { + padding: 8px 20px 8px 30px; + background-color: @tlv_color_t + } + } + } + + sdc-accordion.selected { + /deep/ .expand-collapse-container { + .sdc-accordion-header { + background-color: @main_color_a; + color: @main_color_p; + + .svg-icon { + fill: @main_color_p; + } + } + } + } + + .expand-collapse-sub-title { + max-width: 225px; + display: inline-block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + padding: 10px 0 0 33px; + } + + .expand-collapse-content { + .expand-collapse-title { + padding: 0 10px 0 30px; + } + } + + .module-data-container { + width: 100%; + overflow-y: overlay; + background-color: @tlv_color_v; + border: 1px solid @main_color_a; + border-top: 4px solid @main_color_a; + box-shadow: 0.3px 1px 2px rgba(24, 24, 25, 0.32); + .module-data { + color: @main_color_a; + padding: 10px 0 10px 0; + margin: 0 20px 0 20px; + + .selected-module-property-header { + font-weight: bold; + } + + .selected-module-property-value { + font-family: @font-opensans-regular; + + &.small-font { + font-size: 12px; + } + } + + .module-name-container { + + display: flex; + flex-direction: row; + + .module-name { + font-size: 14px; + width: 75%; + max-width: 240px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .edit-name-container { + float: right; + border-left: 1px solid @main_color_a; + height: 20px; + padding-left: 12px; + + svg-icon { + padding-top: 3px; + fill: @main_color_s; + + &.hand-pointer { + cursor: pointer; + } + + } + } + } + } + + .selected-module-property-container { + flex-direction: row; + display: flex; + + .selected-module-property-value { + text-indent: 2px; + } + } + + /deep/ .expand-collapse-module-data-container { + margin-bottom: 0; + + .sdc-accordion-header { + white-space: nowrap; + line-height: 22px; + padding: 8px 20px 8px 16px; + height: 40px; + background-color: @tlv_color_w; + color: @main_color_l; + border-top: 1px solid @main_color_a; + border-bottom: 1px solid @main_color_a; + width: 100%; + } + + } + + .module-data-list-item { + padding-bottom: 10px; + margin: 0 20px 0 20px; + + .artifact-list-item { + color: @main_color_m; + } + + .module-data-list-item-value { + width: 100%; + max-width: 240px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + &.artifact-info { + font-family: @font-opensans-regular; + font-size: 12px; + } + + &.property-name { + font-weight: 400; + color: @main_color_a; + + .hand-pointer { + cursor: pointer; + } + } + + &.property-info { + color: @func_color_s; + font-family: @font-opensans-regular; + } + } + } + } +} + +.modules-list { + overflow-y: overlay; + flex-grow: 1; +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.component.spec.ts b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.component.spec.ts new file mode 100644 index 0000000000..ab88867cc0 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.component.spec.ts @@ -0,0 +1,133 @@ +import {async, ComponentFixture} from "@angular/core/testing"; +import {HierarchyTabComponent} from "./hierarchy-tab.component"; +import {ConfigureFn, configureTests} from "../../../../../../../../jest/test-config.helper"; +import {NO_ERRORS_SCHEMA} from "@angular/core"; +import {TranslateModule} from "../../../../../../shared/translator/translate.module"; +import {TopologyTemplateService} from "../../../../../../services/component-services/topology-template.service"; +import {WorkspaceService} from "../../../../workspace.service"; +import {ModulesService} from "../../../../../../services/modules.service"; +import {GlobalPipesModule} from "../../../../../../pipes/global-pipes.module"; +import {TranslateService} from "../../../../../../shared/translator/translate.service"; +import {ModalsHandler} from "../../../../../../../utils/modals-handler"; +import {ComponentFactory} from "../../../../../../../utils/component-factory"; +import {NgxsModule} from "@ngxs/store"; +import { SdcUiServices } from "onap-ui-angular"; +import {Observable} from "rxjs"; +import {DisplayModule, Module} from "../../../../../../../models/modules/base-module"; +import {DeploymentGraphService} from "../../../../../composition/deployment/deployment-graph.service"; +import {ComponentMetadata} from "../../../../../../../models/component-metadata"; + +describe('HierarchyTabComponent', () => { + + let fixture: ComponentFixture; + let workspaceService: Partial; + let popoverServiceMock: Partial; + let modulesServiceMock: Partial; + + let editModuleNameInstanceMock = {innerPopoverContent:{instance: { clickButtonEvent: Observable.of("new heat name")}}, + closePopover: jest.fn()}; + let eventMock = {x: 1650, y: 350}; + let moduleMock: Array = [{name: "NewVf2..base_vepdg..module-0", uniqueId: '1'}]; + let selectedModuleMock: DisplayModule = {name: "NewVf2..base_vepdg..module-0", vfInstanceName: "NewVf2", moduleName:"module-0", + heatName: "base_vepdg", uniqueId: '1', updateName: jest.fn().mockImplementation(() => { + selectedModuleMock.name = selectedModuleMock.vfInstanceName + '..' + selectedModuleMock.heatName + '..' + + selectedModuleMock.moduleName;})} + let updateSelectedModuleMock = () => { + selectedModuleMock.heatName = "base_vepdg"; + selectedModuleMock.name = "NewVf2..base_vepdg..module-0"; + fixture.componentInstance.selectedModule = selectedModuleMock; + fixture.componentInstance.modules = moduleMock; + } + beforeEach( + async(() => { + + workspaceService ={ + metadata: { + name: '', + componentType: '' + } + } + popoverServiceMock = { + createPopOverWithInnerComponent: jest.fn().mockImplementation(() => {return editModuleNameInstanceMock}) + } + modulesServiceMock = { + updateModuleMetadata: jest.fn().mockReturnValue(Observable.of({})) + } + + const configure: ConfigureFn = testBed => { + testBed.configureTestingModule({ + declarations: [HierarchyTabComponent], + schemas: [NO_ERRORS_SCHEMA], + imports: [TranslateModule, NgxsModule.forRoot([]), GlobalPipesModule], + providers: [ + {provide: DeploymentGraphService, useValue: {}}, + {provide: ComponentFactory, useValue: {}}, + {provide: TopologyTemplateService, useValue: {}}, + {provide: WorkspaceService, useValue: workspaceService}, + {provide: ModulesService, useValue: modulesServiceMock}, + {provide: TranslateService, useValue: {}}, + {provide: ModalsHandler, useValue: {}}, + {provide: SdcUiServices.PopoverService, useValue: popoverServiceMock} + ] + }); + }; + + configureTests(configure).then(testBed => { + fixture = testBed.createComponent(HierarchyTabComponent); + }); + }) + ); + + it('expected heirarchy component to be defined', () => { + expect(fixture).toBeDefined(); + }); + + it('Update heat name and name sucessfully', () => { + updateSelectedModuleMock(); + fixture.componentInstance.openEditModuleNamePopup(eventMock); + expect(fixture.componentInstance.selectedModule.updateName).toHaveBeenCalled(); + expect(modulesServiceMock.updateModuleMetadata).toHaveBeenCalled(); + expect(fixture.componentInstance.selectedModule.name).toEqual('NewVf2..new heat name..module-0'); + expect(fixture.componentInstance.modules[0].name).toEqual('NewVf2..new heat name..module-0'); + expect(fixture.componentInstance.selectedModule.heatName).toEqual('new heat name'); + }) + it('Try to update heat name and name and get error from server', () => { + updateSelectedModuleMock(); + modulesServiceMock.updateModuleMetadata.mockImplementation(() => Observable.throwError({})); + fixture.componentInstance.openEditModuleNamePopup(eventMock); + expect(fixture.componentInstance.selectedModule.updateName).toHaveBeenCalled(); + expect(modulesServiceMock.updateModuleMetadata).toHaveBeenCalled(); + expect(fixture.componentInstance.modules[0].name).toEqual('NewVf2..base_vepdg..module-0'); + expect(fixture.componentInstance.selectedModule.heatName).toEqual('base_vepdg'); + expect(fixture.componentInstance.selectedModule.name).toEqual('NewVf2..base_vepdg..module-0'); + }) + it('Try to update heat name and name but not find the module with the same uniqueId', () => { + selectedModuleMock.uniqueId = '2' + updateSelectedModuleMock(); + fixture.componentInstance.openEditModuleNamePopup(eventMock); + expect(fixture.componentInstance.selectedModule.updateName).toHaveBeenCalled(); + expect(modulesServiceMock.updateModuleMetadata).not.toHaveBeenCalled(); + expect(fixture.componentInstance.modules[0].name).toEqual('NewVf2..base_vepdg..module-0'); + expect(fixture.componentInstance.selectedModule.heatName).toEqual('base_vepdg'); + expect(fixture.componentInstance.selectedModule.name).toEqual('NewVf2..base_vepdg..module-0'); + selectedModuleMock.uniqueId = '1' + }) + it('Open edit module name popover and change the heat name', () => { + updateSelectedModuleMock(); + spyOn(fixture.componentInstance, 'updateHeatName'); + spyOn(fixture.componentInstance, 'updateOriginalHeatName'); + fixture.componentInstance.openEditModuleNamePopup(eventMock); + expect(popoverServiceMock.createPopOverWithInnerComponent).toHaveBeenCalled(); + expect(fixture.componentInstance.selectedModule.heatName).toEqual("new heat name"); + expect(fixture.componentInstance.updateHeatName).toHaveBeenCalled(); + }) + + + it('Open edit module name popover and not change the heat name', () => { + updateSelectedModuleMock(); + editModuleNameInstanceMock.innerPopoverContent.instance.clickButtonEvent = Observable.of(null); + fixture.componentInstance.openEditModuleNamePopup(eventMock); + expect(popoverServiceMock.createPopOverWithInnerComponent).toHaveBeenCalled(); + expect(fixture.componentInstance.selectedModule.heatName).toEqual("base_vepdg"); + }) +}); \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.component.ts b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.component.ts new file mode 100644 index 0000000000..604b194283 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.component.ts @@ -0,0 +1,139 @@ +import {Component, Input} from "@angular/core"; +import {Component as TopologyTemplate, ComponentInstance, DisplayModule, Module, PropertyModel} from "app/models"; +import {TranslateService} from "app/ng2/shared/translator/translate.service"; +import {ComponentType} from "app/utils/constants"; +import {WorkspaceService} from "../../../../workspace.service"; +import {ModulesService} from "../../../../../../services/modules.service"; +import * as _ from "lodash"; +import {ModalsHandler} from "../../../../../../../utils/modals-handler"; +import {ComponentFactory} from "../../../../../../../utils/component-factory"; +import {Select, Store} from "@ngxs/store"; +import { SdcUiServices } from "onap-ui-angular"; +import { EditModuleName } from "../edit-module-name/edit-module-name.component"; +import {GraphState} from "../../../../../composition/common/store/graph.state"; +import {DeploymentGraphService} from "../../../../../composition/deployment/deployment-graph.service"; +import {OnSidebarOpenOrCloseAction} from "../../../../../composition/common/store/graph.actions"; + +@ Component({ + selector: 'hierarchy-tab', + templateUrl: './hierarchy-tab.component.html', + styleUrls: ['./hierarchy-tab.component.less'], +}) +export class HierarchyTabComponent { + + @Select(GraphState.withSidebar) withSidebar$: boolean; + @Input() isViewOnly: boolean; + public selectedIndex: number; + public selectedModule: DisplayModule; + public isLoading: boolean; + public topologyTemplateName: string; + public topologyTemplateType: string; + public modules: Array = []; + public componentInstances: Array = []; + private editPropertyModalTopologyTemplate: TopologyTemplate; + + constructor(private translateService: TranslateService, + private workspaceService: WorkspaceService, + private deploymentService: DeploymentGraphService, + private modulesService: ModulesService, + private ModalsHandler: ModalsHandler, + private componentFactory: ComponentFactory, + private store: Store, + private popoverService: SdcUiServices.PopoverService) { + this.isLoading = false; + this.topologyTemplateName = this.workspaceService.metadata.name; + this.topologyTemplateType = this.workspaceService.metadata.componentType; + } + + ngOnInit() { + this.modules = this.deploymentService.modules; + this.componentInstances = this.deploymentService.componentInstances; + this.editPropertyModalTopologyTemplate = this.componentFactory.createEmptyComponent(this.topologyTemplateType); + this.editPropertyModalTopologyTemplate.componentInstances = this.deploymentService.componentInstances; + } + + onModuleSelected(module: Module, componentInstanceId?: string): void { + + let onSuccess = (module: DisplayModule) => { + console.log("Module Loaded: ", module); + this.selectedModule = module; + this.isLoading = false; + }; + + let onFailed = () => { + this.isLoading = false; + }; + + if (!this.selectedModule || (this.selectedModule && this.selectedModule.uniqueId != module.uniqueId)) { + this.isLoading = true; + if (this.topologyTemplateType == ComponentType.SERVICE) { + // this.selectedInstanceId = componentInstanceId; + this.modulesService.getComponentInstanceModule(this.topologyTemplateType, this.workspaceService.metadata.uniqueId, componentInstanceId, module.uniqueId).subscribe((resultModule: DisplayModule) => { + onSuccess(resultModule); + }, () => { + onFailed(); + }); + } else { + this.modulesService.getModuleForDisplay(this.topologyTemplateType, this.workspaceService.metadata.uniqueId, module.uniqueId).subscribe((resultModule: DisplayModule) => { + onSuccess(resultModule); + }, () => { + onFailed(); + }); + } + } + } + + updateHeatName(): void { + this.isLoading = true; + let originalName: string = this.selectedModule.name; + + this.selectedModule.updateName(); + let moduleIndex: number = _.indexOf(this.modules, _.find(this.modules, (module: Module) => { + return module.uniqueId === this.selectedModule.uniqueId; + })); + + if (moduleIndex !== -1) { + this.modules[moduleIndex].name = this.selectedModule.name; + this.modulesService.updateModuleMetadata(this.topologyTemplateType, this.workspaceService.metadata.uniqueId, this.modules[moduleIndex]).subscribe(() => { + this.isLoading = false; + }, () => { + this.updateOriginalHeatName(originalName, moduleIndex); + this.modules[moduleIndex].name = originalName; + }); + } else { + this.updateOriginalHeatName(originalName, moduleIndex); + } + }; + + private updateOriginalHeatName(originalName: string, moduleIndex: number){ + this.isLoading = false; + this.selectedModule.name = originalName; + this.selectedModule.heatName = this.selectedModule.name.split('..')[1]; + } + + openEditPropertyModal(property: PropertyModel): void { + this.editPropertyModalTopologyTemplate.setComponentMetadata(this.workspaceService.metadata); + this.ModalsHandler.openEditModulePropertyModal(property, this.editPropertyModalTopologyTemplate, this.selectedModule, this.selectedModule.properties).then(() => { + }); + } + + private getKeys(map: Map) { + return _.keys(map); + } + + private toggleSidebarDisplay = () => { + // this.withSidebar = !this.withSidebar; + this.store.dispatch(new OnSidebarOpenOrCloseAction()); + } + + public openEditModuleNamePopup($event) { + const editModuleNameInstance = this.popoverService.createPopOverWithInnerComponent('Edit Module Name', '', {x:$event.x , y:$event.y }, EditModuleName, {selectModule: _.cloneDeep(this.selectedModule)}, 'top'); + editModuleNameInstance.innerPopoverContent.instance.clickButtonEvent.subscribe((newHeatName) => { + if(newHeatName != null){ + this.selectedModule.heatName = newHeatName; + this.updateHeatName(); + } + editModuleNameInstance.closePopover(); + }) + } +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.module.ts b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.module.ts new file mode 100644 index 0000000000..048ca0c65f --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/deployment/panel/panel-tabs/hierarchy-tab/hierarchy-tab.module.ts @@ -0,0 +1,24 @@ +/** + * Created by ob0695 on 6/4/2018. + */ +import {NgModule} from "@angular/core"; +import {SdcUiComponentsModule} from "onap-ui-angular"; +import {HierarchyTabComponent} from "./hierarchy-tab.component"; +import {UiElementsModule} from "../../../../../../components/ui/ui-elements.module"; +import {TranslateModule} from "../../../../../../shared/translator/translate.module"; +import {CommonModule} from "@angular/common"; +import {GlobalPipesModule} from "../../../../../../pipes/global-pipes.module"; +import { EditModuleName } from "../edit-module-name/edit-module-name.component"; + +@NgModule({ + declarations: [HierarchyTabComponent, EditModuleName], + imports: [CommonModule, + UiElementsModule, + SdcUiComponentsModule, + TranslateModule, + GlobalPipesModule], + entryComponents: [HierarchyTabComponent, EditModuleName], + exports: [HierarchyTabComponent, EditModuleName], +}) +export class HierarchyTabModule { +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-artifact-table/distribution-component-artifact-table.component.html b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-artifact-table/distribution-component-artifact-table.component.html new file mode 100644 index 0000000000..574f2d1bb4 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-artifact-table/distribution-component-artifact-table.component.html @@ -0,0 +1,62 @@ +
+ + + +
+ {{ status.timeStamp | date:'short':'UTC'}} + {{ status.status }} +
+
+
+ + +
+ + + + + {{ componentName }} + +
+
+
+ + +
{{ row.name }}
+
+
+ + +
+ {{ row.url }} + + + + +
+
+
+ + +
{{ getLatestArtifact(row.name).timeStamp | date:'short':'UTC'}}
+
+
+ + +
{{ getLatestArtifact(row.name).status }}
+
+
+
+
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-artifact-table/distribution-component-artifact-table.component.less b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-artifact-table/distribution-component-artifact-table.component.less new file mode 100644 index 0000000000..81b8805792 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-artifact-table/distribution-component-artifact-table.component.less @@ -0,0 +1,78 @@ +:host ::ng-deep { + .ngx-datatable { + > div { + min-height: 5px; + } + } +} + +.datatable-header-cell { + text-align: left; + color: red; +} + +.statusHeaderTable { + color: #000000; + font-family: OpenSans-Bold, sans-serif; + font-size: 12px; + font-weight: bold; + float: left; +} + +.status { + padding-right: 30px; + color: #5a5a5a; + font-family: OpenSans-Regular, sans-serif; + font-size: 12px; +} + +.distributionIDBlock { + display: inline-block; +} + +.distributionRowContainer{ + background-color: #eaeaea; + text-align: center; +} + +.distributionRowLabel { + overflow: hidden; + padding-top: 10px; + color: #000000; + font-family: OpenSans-Semibold, sans-serif; + font-size: 12px; + font-weight: bold; +} + +.distributionRowValue { + color: #263d4d; + font-family: OpenSans-Regular, sans-serif; + font-size: 14px; +} + +.urlValue { + float: left; + color: #263d4d; + font-family: OpenSans-Regular, sans-serif; + font-size: 14px; +} + +.urlCopyIcon { + float: right; + width: 8%; +} + +.ellipsisCell { + width: 92%; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} + + + + + + + + diff --git a/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-artifact-table/distribution-component-artifact-table.component.spec.ts b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-artifact-table/distribution-component-artifact-table.component.spec.ts new file mode 100644 index 0000000000..72b930b6b8 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-artifact-table/distribution-component-artifact-table.component.spec.ts @@ -0,0 +1,90 @@ +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { ComponentFixture } from '@angular/core/testing'; +import { NgxDatatableModule } from '@swimlane/ngx-datatable'; +import { SdcUiServices } from 'onap-ui-angular'; +import { ConfigureFn, configureTests } from '../../../../../../../jest/test-config.helper'; +import { DistributionService } from '../../distribution.service'; +import { DistributionComponentArtifactTableComponent } from './distribution-component-artifact-table.component'; + +describe('DistributionComponentArtifactTableComponent', () => { + let fixture: ComponentFixture; + let distibutionServiceMock: Partial; + + const mockArtifactsForDistributionAndComponentName = [ + { + name: 'Artifact1', + statuses: [ + {timeStamp: '7/25/2019 12:48AM', status: 'DEPLOY_OK'}, + {timeStamp: '7/25/2019 12:48AM', status: 'DOWNLOAD_OK'}, + {timeStamp: '7/25/2019 12:48AM', status: 'NOTIFIED'} + ], + url: 'URL1', + }, + { + name: 'Artifact2', + statuses: [ + {timeStamp: '7/26/2019 12:48AM', status: 'STATUS_TO_DISPLAY'}, + {timeStamp: '7/25/2019 12:48AM', status: 'DOWNLOAD_OK'}, + {timeStamp: '7/25/2019 12:48AM', status: 'NOTIFIED'} + ], + url: 'URL2', + }, + { + name: 'ArtifactWithNoStatuses', + url: 'URL2', + } + ]; + + beforeEach(() => { + + distibutionServiceMock = { + getArtifactstByDistributionIDAndComponentsName: jest.fn().mockReturnValue(mockArtifactsForDistributionAndComponentName), + }; + + const configure: ConfigureFn = (testBed) => { + testBed.configureTestingModule({ + declarations: [DistributionComponentArtifactTableComponent], + imports: [NgxDatatableModule], + schemas: [NO_ERRORS_SCHEMA], + providers: [ + {provide: DistributionService, useValue: distibutionServiceMock} + ], + }); + }; + + configureTests(configure).then((testBed) => { + fixture = testBed.createComponent(DistributionComponentArtifactTableComponent); + }); + + }); + + it('Get Latest Artifact (status and timeStamp) - So the Component Table will display the last time stamp of the notification', async () => { + await fixture.componentInstance.ngOnInit(); + expect(fixture.componentInstance.getLatestArtifact('Artifact2')).toEqual({status: 'STATUS_TO_DISPLAY', timeStamp: '7/26/2019 12:48AM'}); + expect(fixture.componentInstance.getLatestArtifact('ArtifactWithNoStatuses')).toEqual(null); + }); + + it('Once the Distribution Component Artifact Table Component is created - artifacts will keep the relevant artifacts for a specific distributionID and Component Name', async () => { + await fixture.componentInstance.ngOnInit(); + // tslint:disable:no-string-literal + expect(fixture.componentInstance.artifacts.length).toBe(3); + expect(fixture.componentInstance.artifacts[0].name).toBe('Artifact1'); + expect(fixture.componentInstance.artifacts[0].url).toBe('URL1'); + expect(fixture.componentInstance.artifacts[0].statuses.length).toBe(3); + + expect(fixture.componentInstance.artifacts[1].name).toBe('Artifact2'); + }); + + it('Once the Distribution Component Artifact Table Component is created for Modal- artifacts will keep the relevant artifacts for a ' + + 'specific distributionID and Component Name filtered by Status', async () => { + fixture.componentInstance.statusFilter = 'DOWNLOAD_OK'; + await fixture.componentInstance.ngOnInit(); + expect(fixture.componentInstance.artifacts.length).toBe(3); + expect(fixture.componentInstance.artifacts[0].name).toBe('Artifact1'); + expect(fixture.componentInstance.artifacts[0].url).toBe('URL1'); + + expect(fixture.componentInstance.artifacts[0].statuses.length).toBe(1); + expect(fixture.componentInstance.artifacts[0].statuses[0]).toEqual({status: 'DOWNLOAD_OK', timeStamp: '7/25/2019 12:48AM'}); + + }); +}); diff --git a/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-artifact-table/distribution-component-artifact-table.component.ts b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-artifact-table/distribution-component-artifact-table.component.ts new file mode 100644 index 0000000000..af9aef5c64 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-artifact-table/distribution-component-artifact-table.component.ts @@ -0,0 +1,68 @@ +import { Component, Input, OnInit, ViewChild } from '@angular/core'; +import * as _ from 'lodash'; +import { DistributionService } from '../../distribution.service'; + +// tslint:disable:no-string-literal + +@Component({ + selector: 'app-distribution-component-artifact-table', + templateUrl: './distribution-component-artifact-table.component.html', + styleUrls: ['./distribution-component-artifact-table.component.less'] +}) +export class DistributionComponentArtifactTableComponent implements OnInit { + + @ViewChild('statusTable', {}) table: any; + + @Input() componentName: string; + @Input() rowDistributionID: string; + @Input() statusFilter: string; + + public artifacts = []; + + constructor(private distributionService: DistributionService) { + } + + ngOnInit() { + this.artifacts = this.distributionService.getArtifactstByDistributionIDAndComponentsName(this.rowDistributionID, this.componentName); + if (this.statusFilter) { + this.artifacts.forEach( + (artifact) => { + artifact.statuses = _.filter(artifact.statuses, {status: this.statusFilter}); + }); + } + } + + public getLatestArtifact(artifactName: string) { + const selectedArtifact = this.artifacts.filter((artifact) => artifact.name === artifactName); + if (selectedArtifact && selectedArtifact[0] && selectedArtifact[0]['statuses'] && selectedArtifact[0]['statuses'][0]) { + return selectedArtifact[0]['statuses'][0]; + } else { + return null; + } + } + + private copyToClipboard(urlToCopy: any) { + + const inputForCopyToClipboard = document.getElementById('inputForCopyToClipboard') as HTMLInputElement; + inputForCopyToClipboard.value = urlToCopy; + /* Select the text field */ + inputForCopyToClipboard.select(); + + /* Copy the text inside the text field */ + document.execCommand('copy'); + + } + + private generateDataTestID(preFix: string, componentName: string, artifactName: string, status?: string) { + if (!status) { + return preFix + componentName + '_' + artifactName; + } else { + return preFix + status + '_' + componentName + '_' + artifactName; + } + } + + private expandRow(row: any) { + this.table.rowDetail.toggleExpandRow(row); + } + +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-table.component.html b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-table.component.html new file mode 100644 index 0000000000..fa5a9ad7fb --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-table.component.html @@ -0,0 +1,47 @@ +
+
+ Total Artifacts {{ getTotalArtifactsForDistributionID(rowDistributionID) }} + Notified {{ getLengthArtifactsForDistributionIDByStatus(rowDistributionID, 'NOTIFIED') }} + Downloaded {{ getLengthArtifactsForDistributionIDByStatus(rowDistributionID, 'DOWNLOAD_OK') }} + Deployed {{ getLengthArtifactsForDistributionIDByStatus(rowDistributionID, 'DEPLOY_OK') }} + Not Notified {{ getLengthArtifactsForDistributionIDByStatus(rowDistributionID, 'NOT_NOTIFIED') }} + Deploy Errors {{ getLengthArtifactsForDistributionIDByStatus(rowDistributionID, 'DEPLOY_ERROR') }} + Download Errors {{ getLengthArtifactsForDistributionIDByStatus(rowDistributionID, 'DOWNLOAD_ERROR') }} +
+ + + + +
+
+ + + + {{ component }} {{ getTotalArtifactsForDistributionID(rowDistributionID, component) }} + Notified {{ getLengthArtifactsForDistributionIDByStatus(rowDistributionID, 'NOTIFIED', component) }} + Downloaded {{ getLengthArtifactsForDistributionIDByStatus(rowDistributionID, 'DOWNLOAD_OK', component) }} + Deployed {{ getLengthArtifactsForDistributionIDByStatus(rowDistributionID, 'DEPLOY_OK', component) }} + Not Notified {{ getLengthArtifactsForDistributionIDByStatus(rowDistributionID, 'NOT_NOTIFIED', component) }} + {{ getMSOStatus (rowDistributionID, component) }} + Deploy Errors {{ getLengthArtifactsForDistributionIDByStatus(rowDistributionID, 'DEPLOY_ERROR', component) }} + Download Errors {{ getLengthArtifactsForDistributionIDByStatus(rowDistributionID, 'DOWNLOAD_ERROR', component) }} +
+ + + +
+ +
+
+
+ diff --git a/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-table.component.less b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-table.component.less new file mode 100644 index 0000000000..3eab18ca14 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-table.component.less @@ -0,0 +1,66 @@ +.red { + color: red; +} + +.green { + color: green; +} + +.msoStatus { + padding-left: 5px; +} + +.blue { + color: #009fdb; + font-family: OpenSans-Semibold, sans-serif; + font-size: 14px; +} + +.rightVerticalSeperator { + border-right: 1px solid #d2d2d2; + padding-left: 5px; + padding-right: 5px; + cursor: pointer; +} + +.rightVerticalSeperatorComponent { + border-right: 1px solid #d2d2d2; + padding-left: 5px; + padding-right: 5px; +} + +.floatRight{ + float: right; +} + +.distributionSummary { + padding-top: 5px; + padding-bottom: 5px; + background-color: #eaeaea; + padding-left: 25px; + padding-right: 25px; +} + +.componentSummary { + margin-top: 5px; + margin-bottom: 5px; + padding-top: 5px; + padding-bottom: 5px; + background-color: #eaeaea; + padding-left: 25px; + padding-right: 25px; +} + +.componentShiftLeft { + margin-left: 15px; +} + +.titleSummaryFontSettings { + color: #191919; + font-family: OpenSans-Regular, sans-serif; + font-size: 14px; +} + + + + diff --git a/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-table.component.spec.ts b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-table.component.spec.ts new file mode 100644 index 0000000000..ff89b92fd8 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-table.component.spec.ts @@ -0,0 +1,47 @@ +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { ComponentFixture } from '@angular/core/testing'; +import { NgxDatatableModule } from '@swimlane/ngx-datatable'; +import { SdcUiServices } from 'onap-ui-angular'; +import { ConfigureFn, configureTests } from '../../../../../../jest/test-config.helper'; +import { DistributionService } from '../distribution.service'; +import { DistributionComponentTableComponent } from './distribution-component-table.component'; + +describe('DistributionComponentTableComponent', () => { + let fixture: ComponentFixture; + let distibutionServiceMock: Partial; + + const mockComponentsForDistribution = ['Consumer1', 'Consumer2']; + + beforeEach(() => { + + distibutionServiceMock = { + getComponentsByDistributionID: jest.fn().mockReturnValue(mockComponentsForDistribution), + getArtifactstByDistributionIDAndComponentsName: jest.fn(), + getArtifactsForDistributionIDAndComponentByStatus: jest.fn() + }; + + const configure: ConfigureFn = (testBed) => { + testBed.configureTestingModule({ + declarations: [DistributionComponentTableComponent], + imports: [NgxDatatableModule], + schemas: [NO_ERRORS_SCHEMA], + providers: [ + {provide: DistributionService, useValue: distibutionServiceMock}, + {provide: SdcUiServices.ModalService, useValue: {}} + ], + }); + }; + + configureTests(configure).then((testBed) => { + fixture = testBed.createComponent(DistributionComponentTableComponent); + }); + + }); + + it('Once the Distribution Component Table Component is created - components will keep the relevant components for a specific distributionID', async () => { + await fixture.componentInstance.ngOnInit(); + expect(fixture.componentInstance.components.length).toBe(2); + expect(fixture.componentInstance.components[0]).toBe('Consumer1'); + expect(fixture.componentInstance.components[1]).toBe('Consumer2'); + }); +}); diff --git a/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-table.component.ts b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-table.component.ts new file mode 100644 index 0000000000..e3aaf9d639 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution-component-table/distribution-component-table.component.ts @@ -0,0 +1,104 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { SdcUiCommon, SdcUiComponents, SdcUiServices } from 'onap-ui-angular'; +import { ModalComponent } from 'onap-ui-angular/dist/modals/modal.component'; +import { DistributionComponent } from '../distribution.component'; +import { DistributionService } from '../distribution.service'; + +@Component({ + selector: 'app-distribution-component-table', + templateUrl: './distribution-component-table.component.html', + styleUrls: ['./distribution-component-table.component.less'] +}) +export class DistributionComponentTableComponent implements OnInit { + + @Input() rowDistributionID: string; + @Input() isModal: boolean = false; + @Input() statusFilter: string; + public components = []; + private customModalInstance: ModalComponent; + private expanded = []; + constructor(private distributionService: DistributionService, + private modalService: SdcUiServices.ModalService) { + } + + ngOnInit() { + this.initComponents(); + } + + private generateTotalComponentArtifactsLabel(componentName: any, status: string): string { + return 'total' + componentName + status + 'ArtifactsLabel'; + } + + private generateExpandDataTestID(componentName: string) { + return 'expandIcon_' + componentName; + } + + private initComponents() { + this.components = this.distributionService.getComponentsByDistributionID(this.rowDistributionID); + this.components.map((component) => this.expanded.push({componentName: component, expanded: false})); + } + + private getTotalArtifactsForDistributionID(distributionID: string, componentName?: string): number { + return this.distributionService.getArtifactstByDistributionIDAndComponentsName(distributionID, componentName).length; + } + + private getLengthArtifactsForDistributionIDByStatus(distributionID: string, statusToSerach: string, componentName?: string): number { + if (componentName) { + return this.distributionService.getArtifactsForDistributionIDAndComponentByStatus(distributionID, statusToSerach, componentName).length; + } else { + return this.distributionService.getArtifactsForDistributionIDAndComponentByStatus(distributionID, statusToSerach).length; + } + } + + private openModal(rowDistributionID: string, statusFilter: string) { + + const title: string = 'Distribution by Status'; + const attributeModalConfig = { + title, + size: 'sdc-xl', + type: SdcUiCommon.ModalType.custom, + buttons: [ + { + id: 'close', + text: 'Close', + size: 'sm', + closeModal: true, + disabled: false, + } + ] as SdcUiCommon.IModalButtonComponent[] + }; + + this.customModalInstance = this.modalService.openCustomModal(attributeModalConfig, DistributionComponent, { + // inputs + rowDistributionID, + statusFilter, + isModal: true, + }); + } + + private expandRow(componentName: string) { + console.log('Should expand componentSummary for componentName = ' + componentName); + const selectedComponent = this.expanded.find((component) => component.componentName === componentName); + // tslint:disable:no-string-literal + const selectedComponentExpandedVal = selectedComponent['expanded']; + // this.expanded = !this.expanded; + for (const i in this.expanded) { + if (this.expanded[i].componentName === componentName) { + this.expanded[i].expanded = !this.expanded[i].expanded; + break; //Stop this loop, we found it! + } + } + const selectedComponentAfter = this.expanded.find((component) => component.componentName === componentName); + const selectedComponentExpandedValAfter = selectedComponentAfter['expanded']; + } + + private isExpanded(componentName: string) { + const selectedComponent = this.expanded.find((component) => component.componentName === componentName); + return selectedComponent['expanded']; + } + + + private getMSOStatus(rowDistributionID: string, componentName: string): string { + return this.distributionService.getMSOStatus(rowDistributionID, componentName); + } +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.component.html b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.component.html new file mode 100644 index 0000000000..d0cacb054e --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.component.html @@ -0,0 +1,80 @@ +
+
+
DISTRIBUTION [{{distributions.length}}]
+
+ + +
+
+
No Distributions To Present
+
+ +
+ + + + + + + + +
+ + +
+
+
{{ row.distributionID }}
+
+
+
+ + +
{{ row.userId }}
+
+
+ + +
{{ row.timestamp }}
+
+
+ + +
+ + + + + {{ row.deployementStatus }} + + + + +
+
+
+
+
diff --git a/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.component.less b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.component.less new file mode 100644 index 0000000000..b630881fdc --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.component.less @@ -0,0 +1,92 @@ +:host ::ng-deep { + .ngx-datatable { + > div { + min-height: 500px; + datatable-body { + max-height: max-content; + } + } + } +} + +.w-sdc-distribution-view-header { + display: flex; + -webkit-justify-content: space-between; + margin: 0 25px 5px 40px; + + .header-spacer { + flex-grow: 5; + } + + .w-sdc-distribution-view-title{ + color: #191919; + font-family: OpenSans-Regular, sans-serif; + font-size: 14px; + line-height: 30px; + + + .blue-font { + color: #009fdb; + font-family: OpenSans-Semibold, sans-serif; + font-size: 14px; + } + } + +} + +.distribution-page { + max-height: 150px; +} + + .distributionIDBlock { + display: inline-block; + } + + .expand-collapse-cell { + display: inline-block; + } + + .statusIcon { + display: inline-block; + margin-right: 10px; + } + + .btnMarkAsDistributed { + float: right; + background-color: #E5F3FF; + border: 1px solid #8DCCD5; + width: 55px; + height: 21px; + text-align: center; + } + + .distributionRowContainer{ + background-color: #eaeaea; + text-align: center; + } + + .distributionRowLabel { + overflow: hidden; + padding-top: 10px; + color: #000000; + font-family: OpenSans-Semibold, sans-serif; + font-size: 12px; + font-weight: bold; + } + + .distributionRowValue { + color: #263d4d; + font-family: OpenSans-Regular, sans-serif; + font-size: 14px; + } + +.ellipsisCell { + width: 92%; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} + + + + diff --git a/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.component.spec.ts b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.component.spec.ts new file mode 100644 index 0000000000..e6c9c239e1 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.component.spec.ts @@ -0,0 +1,92 @@ +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { ComponentFixture } from '@angular/core/testing'; +import { NgxDatatableModule } from '@swimlane/ngx-datatable'; +import { SdcUiServices } from 'onap-ui-angular'; +import { ConfigureFn, configureTests } from '../../../../../jest/test-config.helper'; +import { ComponentMetadata } from '../../../../models/component-metadata'; +import { AuthenticationService } from '../../../services/authentication.service'; +import { WorkspaceService } from '../workspace.service'; +import { DistributionComponent } from './distribution.component'; +import { DistributionService } from './distribution.service'; +import {EventListenerService} from "../../../../services/event-listener-service"; + +describe('DistributionComponent', () => { + let fixture: ComponentFixture; + let distibutionServiceMock: Partial; + let workspaceServiceMock: Partial; + let loaderServiceMock: Partial; + let authenticationServiceMock: Partial ; + let eventListenerService: Partial ; + + const mockDistributionListFromService = [ + { + deployementStatus: 'Distributed', + distributionID: '1', + timestamp: '2019-07-21 08:37:02.834 UTC', + userId: 'Aretha Franklin(op0001)' + }, { + deployementStatus: 'Distributed', + distributionID: '2', + timestamp: '2019-07-21 09:37:02.834 UTC', + userId: 'Aretha Franklin(op0001)' + }]; + + beforeEach(() => { + + distibutionServiceMock = { + initDistributionsList: jest.fn(), + getDistributionList: jest.fn().mockReturnValue(mockDistributionListFromService), + initDistributionsStatusForDistributionID: jest.fn() + }; + + const componentMetadata = new ComponentMetadata(); + componentMetadata.uuid = '111'; + + workspaceServiceMock = { + metadata : componentMetadata + }; + + authenticationServiceMock = { + getLoggedinUser: jest.fn().mockReturnValue({role: 'designer'}) + }; + + eventListenerService = { + registerObserverCallback: jest.fn(), + unRegisterObserver: jest.fn() + } + + loaderServiceMock = { + activate: jest.fn(), + deactivate: jest.fn() + }; + + const configure: ConfigureFn = (testBed) => { + testBed.configureTestingModule({ + declarations: [DistributionComponent], + imports: [NgxDatatableModule], + schemas: [NO_ERRORS_SCHEMA], + providers: [ + {provide: DistributionService, useValue: distibutionServiceMock}, + {provide: WorkspaceService, useValue: workspaceServiceMock}, + {provide: SdcUiServices.LoaderService, useValue: loaderServiceMock}, + {provide: AuthenticationService, useValue: authenticationServiceMock}, + {provide: EventListenerService, useValue: eventListenerService} + ], + }); + }; + + configureTests(configure).then((testBed) => { + fixture = testBed.createComponent(DistributionComponent); + }); + + }); + + it('Once the Distribution Component is created - distributionsResponseFromServer save all the distributions from the Service', async () => { + fixture.componentInstance.componentUuid = 'componentUid'; + fixture.componentInstance.rowDistributionID = null; + fixture.componentInstance.isModal = false; + + await fixture.componentInstance.ngOnInit(); + expect(fixture.componentInstance.distributions.length).toBe(2); + }); +}); diff --git a/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.component.ts b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.component.ts new file mode 100644 index 0000000000..ca1b6292d3 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.component.ts @@ -0,0 +1,117 @@ +import { Component, Input, OnInit, ViewChild } from '@angular/core'; +import { SdcUiCommon, SdcUiServices } from 'onap-ui-angular'; +import { EventListenerService } from '../../../../services/event-listener-service'; +import { AuthenticationService } from '../../../services/authentication.service'; +import { WorkspaceService } from '../workspace.service'; +import { DistributionService } from './distribution.service'; +import { EVENTS } from '../../../../utils/constants'; + +@Component({ + selector: 'distribution', + templateUrl: './distribution.component.html', + styleUrls: ['../../../../../assets/styles/table-style.less', './distribution.component.less'] +}) +export class DistributionComponent implements OnInit { + + @ViewChild('distributionTable', { }) table: any; + + @Input() isModal: boolean = false; + @Input() statusFilter: string; + @Input() rowDistributionID: string; + public componentUuid: string; + public distributions = []; + private expanded: any = {}; + private serviceHasDistibutions: boolean = false; + private readonly uniqueId: string; + private userRole: string; + + constructor(private workspaceService: WorkspaceService, + private distributionService: DistributionService, + private loaderService: SdcUiServices.LoaderService, + private authService: AuthenticationService, + private eventListenerService: EventListenerService) { + this.componentUuid = this.workspaceService.metadata.uuid; + this.uniqueId = this.workspaceService.metadata.uniqueId; + } + + + + async ngOnInit() { + this.userRole = this.authService.getLoggedinUser().role; + this.eventListenerService.registerObserverCallback(EVENTS.ON_DISTRIBUTION_SUCCESS, async () => { + await this.refreshDistributions(); + }); + await this.initDistributions(this.componentUuid, this.rowDistributionID); + } + + ngOnDestroy(): void { + this.eventListenerService.unRegisterObserver(EVENTS.ON_DISTRIBUTION_SUCCESS); + } + + async initDistributions(componentUuid: string, specificDistributionID?: string) { + this.loaderService.activate(); + await this.distributionService.initDistributionsList(componentUuid); + this.distributions = this.distributionService.getDistributionList(); + this.distributions.length > 0 ? this.serviceHasDistibutions = true : this.serviceHasDistibutions = false; + if (specificDistributionID) { + this.distributions = this.distributionService.getDistributionList(specificDistributionID); + } + this.loaderService.deactivate(); + } + + getIconName(rowStatus: string ) { + if (rowStatus === 'Distributed') { + return 'distributed'; + } + if (rowStatus === 'Deployed') { + return 'v-circle'; + } + } + + getIconMode(rowStatus: string) { + if (rowStatus === 'Distributed') { + return 'primary'; + } + if (rowStatus === 'Deployed') { + return 'secondary'; + } + } + + private async markDeploy(distributionID: string, status: string) { + if (status === 'Distributed') { + console.log('Should send MarkDeploy POST Request ServiceID:' + this.uniqueId + ' DISTID:' + distributionID); + await this.distributionService.markDeploy(this.uniqueId, distributionID); + this.refreshDistributions(); + } + } + + private async refreshDistributions() { + await this.initDistributions(this.componentUuid); + } + + private updateFilter(event) { + const val = event.target.value.toLowerCase(); + + // filter our data + this.distributions = this.distributionService.getDistributionList().filter((distribution: any[]) => { + return !val || + // tslint:disable:no-string-literal + distribution['distributionID'].toLowerCase().indexOf(val) !== -1; + }); + } + + private generateDataTestID(preFix: string, distributionID: string, isModal?: boolean ): string { + if (isModal) { + return preFix + distributionID.substring(0, 5) + '_Modal'; + } else { + return preFix + distributionID.substring(0, 5); + } + } + + private async expandRow(row: any, expanded: boolean) { + if (!expanded) { + await this.distributionService.initDistributionsStatusForDistributionID(row.distributionID); + } + this.table.rowDetail.toggleExpandRow(row); + } +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.module.ts b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.module.ts new file mode 100644 index 0000000000..723a6d8c0a --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.module.ts @@ -0,0 +1,34 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { NgxDatatableModule } from '@swimlane/ngx-datatable'; +import { SdcUiComponentsModule } from 'onap-ui-angular'; +import { DistributionComponentArtifactTableComponent } from './distribution-component-table/distribution-component-artifact-table/distribution-component-artifact-table.component'; +import { DistributionComponentTableComponent } from './distribution-component-table/distribution-component-table.component'; +import { DistributionComponent } from './distribution.component'; +import { DistributionService } from './distribution.service'; + +@NgModule({ + declarations: [ + DistributionComponent, + DistributionComponentTableComponent, + DistributionComponentArtifactTableComponent, + ], + imports: [ + // TranslateModule, + CommonModule, + SdcUiComponentsModule, + NgxDatatableModule, + ], + exports: [ + DistributionComponent, + DistributionComponentTableComponent + ], + entryComponents: [ + DistributionComponent, + DistributionComponentTableComponent, + DistributionComponentArtifactTableComponent + ], + providers: [DistributionService] +}) +export class DistributionModule { +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.service.ts b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.service.ts new file mode 100644 index 0000000000..ed6791c5c1 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/disribution/distribution.service.ts @@ -0,0 +1,233 @@ +import { HttpClient } from '@angular/common/http'; +import { Inject, Injectable } from '@angular/core'; +import { tap } from 'rxjs/operators'; +import { Distribution } from '../../../../models/distribution'; +import { ISdcConfig, SdcConfigToken } from '../../../config/sdc-config.config'; + +@Injectable() +export class DistributionService { + protected baseUrl; + private distributionList = []; + private distributionStatusesMap = {}; + + // tslint:disable:no-string-literal + + constructor(protected http: HttpClient, @Inject(SdcConfigToken) sdcConfig: ISdcConfig) { + this.baseUrl = sdcConfig.api.root + sdcConfig.api.component_api_root; + } + + // Once the distribution page is loaded or when the user wants to refresh the list + async initDistributionsList(componentUuid: string): Promise { + const distributionsListURL = this.baseUrl + 'services/' + componentUuid + '/distribution'; + const res = this.http.get(distributionsListURL).pipe(tap( (result) => { + this.distributionList = result['distributionStatusOfServiceList']; + this.insertDistrbutionsToMap(); + } )); + return res.toPromise(); + } + + // Once the user click on the relevant distribution ID in the distribution table (open and close) + async initDistributionsStatusForDistributionID(distributionID: string): Promise { + const distributionStatus = this.baseUrl + 'services/distribution/' + distributionID; + const res = this.http.get(distributionStatus).pipe(tap( (result) => { + this.insertDistributionStatusToDistributionsMap(distributionID, result['distributionStatusList']); + } )); + return res.toPromise(); + } + + public getDistributionList(specificDistributionID?: string) { + if (specificDistributionID) { + return this.distributionList.filter((distribution) => { + return distribution['distributionID'] === specificDistributionID; + }); + } else { + return this.distributionList; + } + } + + public getComponentsByDistributionID(distributionID: string) { + const components = []; + const distributionStatusMap = this.getStatusMapForDistributionID(distributionID); + if (distributionStatusMap) { + distributionStatusMap.forEach((component) => components.push(component.componentID)); + } + return components; + } + + // get array of artifacts per distributionID w/o componentName, sliced by artifact status + public getArtifactsForDistributionIDAndComponentByStatus(distributionID: string, statusToSearch: string, componentName?: string) { + const filteredArtifactsByStatus = []; + + if (componentName) { + this.getArtifactstByDistributionIDAndComponentsName(distributionID, componentName).forEach ( (artifact) => { + if (this.artifactStatusHasMatch(artifact, statusToSearch)) { + filteredArtifactsByStatus.push(artifact); + } + } ); + } else { + this.getArtifactstByDistributionIDAndComponentsName(distributionID).forEach ( (artifact) => { + if (this.artifactStatusHasMatch(artifact, statusToSearch)) { + filteredArtifactsByStatus.push(artifact); + } + } ); + } + return filteredArtifactsByStatus; + } + + public getArtifactstByDistributionIDAndComponentsName(distributionID: string, componentName?: string): any[] { + const artifacts = []; + if (this.getStatusMapForDistributionID(distributionID)) { + if (componentName) { + if (this.getStatusMapForDistributionID(distributionID).filter((component) => component.componentID === componentName).length > 0) { + const artifactsArr = this.getStatusMapForDistributionID(distributionID).filter((component) => component.componentID === componentName)[0]['artifacts'] + if (artifactsArr.length > 0) { + artifactsArr.forEach((artifact) => { + const artifactObj = { + url: artifact.artifactUrl, + name: artifact.artifactName, + statuses: artifact.statuses + }; + artifacts.push(artifactObj); + }); + } + } + } else { + const components = this.getComponentsByDistributionID(distributionID); + components.forEach((componentName) => { + if (this.getStatusMapForDistributionID(distributionID).filter((component) => component.componentID === componentName).length > 0) { + const artifactsArr = this.getStatusMapForDistributionID(distributionID).filter((component) => component.componentID === componentName)[0]['artifacts'] + if (artifactsArr.length > 0) { + artifactsArr.forEach((artifact) => { + const artifactObj = { + url: artifact.artifactUrl, + name: artifact.artifactName, + statuses: artifact.statuses + }; + artifacts.push(artifactObj); + }); + } + } + }); + } + } + return artifacts; + } + + public getStatusMapForDistributionID(distributionID: string) { + return this.distributionStatusesMap[distributionID]; + } + + public markDeploy(uniqueId: string, distributionID: string): Promise { + const distributionStatus = this.baseUrl + 'services/' + uniqueId + '/distribution/' + distributionID + '/markDeployed'; + const res = this.http.post(distributionStatus, {}).pipe(tap( (result) => { + console.log(result); + } )); + return res.toPromise(); + } + + public getMSOStatus(distributionID: string, componentName: string): string { + const msoStatus = this.distributionStatusesMap[distributionID].filter((component) => component.componentID === componentName)[0].msoStatus; + return msoStatus ? msoStatus : ''; + } + + private artifactStatusHasMatch(artifact: any, statusToSerach: string) { + for (let i = 0; i < artifact.statuses.length; i++) { + if (artifact.statuses[i].status === statusToSerach) { + return true; + } + } + return false; + } + + private insertDistributionStatusToDistributionsMap(distributionID: string, distributionStatusMapResponseFromServer: object[]) { + + // // Clear the Distribution ID array - to avoid statuses duplications + const distribution = this.distributionStatusesMap[distributionID]; + distribution.length = 0; + + // Sort the response of statuses from Server, so it will be easy to pop the latest status when it will be required + const sortedResponseByTimeStamp = distributionStatusMapResponseFromServer.sort((a, b) => b['timestamp'] - a['timestamp']) + + sortedResponseByTimeStamp.map((distributionStatus) => { + const formattedDate = this.formatDate(distributionStatus['timestamp']); + + // if (distributionStatus['url'] === null) { + // distributionStatus['url'] = ""; + // } + + const detailedArtifactStatus = { + componentID: distributionStatus['omfComponentID'], + artifactName: distributionStatus['url']? distributionStatus['url'].split('/').pop() : '', + url: distributionStatus['url'], + time: distributionStatus['timestamp'], + status: distributionStatus['status'], + }; + + + + // Add Component to this.distributionStatusesMap in case not exist. + let componentPosition = _.findIndex(distribution, {componentID: detailedArtifactStatus.componentID}) + + if (componentPosition === -1) { + this.addComponentIdToDistributionStatusMap(distributionID, detailedArtifactStatus.componentID); + componentPosition = distribution.length - 1; + } + + const component = distribution[componentPosition]; + + + // Add Artifact to this.distributionStatusesMap[componentID] in case not exist. + let artifactPosition = _.findIndex(component.artifacts, {artifactUrl: detailedArtifactStatus.url}) + + if (artifactPosition === -1) { + this.addArtifactToComponentId(distributionID, componentPosition, detailedArtifactStatus.artifactName, detailedArtifactStatus.url); + artifactPosition = component.artifacts.length - 1; + } + + + // Add status to relevat artifact in relevent componentID. + if (detailedArtifactStatus.url) { + // Case where there is a url -> should add its status + component.artifacts[artifactPosition].statuses.push({ + timeStamp: detailedArtifactStatus.time, + status: detailedArtifactStatus.status + }); + } else { + // Should update the Component -> status from MSO + this.distributionStatusesMap[distributionID][componentPosition].msoStatus = detailedArtifactStatus.status; + } + + + }); + } + + private addComponentIdToDistributionStatusMap(distributionID: string, componentIDValue: string) { + this.distributionStatusesMap[distributionID].push({ + componentID: componentIDValue, + msoStatus: null, + artifacts: [] + }); + } + + private addArtifactToComponentId(distributionID: string, componentPosition: number, artifactNameValue: string, artifactURLValue: any) { + if (artifactNameValue) { + this.distributionStatusesMap[distributionID][componentPosition].artifacts.push({ + artifactName: artifactNameValue, + artifactUrl: artifactURLValue, + statuses: [] + }); + } + } + + private insertDistrbutionsToMap() { + this.distributionList.map((distribution) => this.distributionStatusesMap[distribution.distributionID] = []); + } + + private formatDate(epochTime: string) { + const intEpochTime = new Date(parseInt(epochTime, 10)); + const amOrPm = (intEpochTime.getHours() + 24) % 24 > 12 ? 'PM' : 'AM'; + const formattedDate = (intEpochTime.getMonth() + 1) + '/' + intEpochTime.getDate() + '/' + intEpochTime.getFullYear() + ' ' + intEpochTime.getHours() + ':' + + intEpochTime.getMinutes() + amOrPm; + return formattedDate; + } +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/information-artifact/__snapshots__/informational-artifact-page.spec.ts.snap b/catalog-ui/src/app/ng2/pages/workspace/information-artifact/__snapshots__/informational-artifact-page.spec.ts.snap new file mode 100644 index 0000000000..1a19b36cfb --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/information-artifact/__snapshots__/informational-artifact-page.spec.ts.snap @@ -0,0 +1,40 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`informational artifacts page should match current snapshot of informational artifact pages component 1`] = ` + +
+ + +
+ + + + + + + + + +
+
+
+
+`; diff --git a/catalog-ui/src/app/ng2/pages/workspace/information-artifact/information-artifact-page.component.html b/catalog-ui/src/app/ng2/pages/workspace/information-artifact/information-artifact-page.component.html new file mode 100644 index 0000000000..cff33258ae --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/information-artifact/information-artifact-page.component.html @@ -0,0 +1,82 @@ +
+ + + + +
{{row.description}}
+
+
+ + +
+ + {{row.artifactDisplayName }} +
+
+
+ + + {{row.artifactType}} + + + + + {{ row.artifactVersion }} + + + + + {{ row.artifactUUID }} + + + + +
+ + + +
+
+
+ + + +
+ + +
+
+
+
+
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/information-artifact/information-artifact-page.component.less b/catalog-ui/src/app/ng2/pages/workspace/information-artifact/information-artifact-page.component.less new file mode 100644 index 0000000000..b69e511f70 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/information-artifact/information-artifact-page.component.less @@ -0,0 +1,29 @@ +.information-artifact-page { + + .add-artifact-btn { + display: flex; + cursor: pointer; + justify-content: flex-end; + margin-bottom: 10px; + } + .download-artifact-button { + display: flex; + justify-content: center; + + .action-icon{ + margin-right: 10px; + } + } + + .add-artifacts-dynamic-btn-list { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + margin: 20px 0px; + .add-artifacts-dynamic-btn{ + width: 350px; + margin-top: 15px; + } + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/information-artifact/information-artifact-page.component.ts b/catalog-ui/src/app/ng2/pages/workspace/information-artifact/information-artifact-page.component.ts new file mode 100644 index 0000000000..a6804a43c6 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/information-artifact/information-artifact-page.component.ts @@ -0,0 +1,69 @@ +import {Component, OnInit, ViewChild} from "@angular/core"; +import {WorkspaceService} from "../workspace.service"; +import {SdcUiCommon, SdcUiComponents, SdcUiServices} from "onap-ui-angular"; +import {TopologyTemplateService} from "../../../services/component-services/topology-template.service"; +import * as _ from "lodash"; +import {ArtifactGroupType, ArtifactType} from "../../../../utils/constants"; +import {ArtifactsService} from "../../../components/forms/artifacts-form/artifacts.service"; +import {DeleteArtifactAction, GetArtifactsByTypeAction} from "../../../store/actions/artifacts.action"; +import {Select, Store} from "@ngxs/store"; +import {Observable} from "rxjs/index"; +import {ArtifactsState} from "../../../store/states/artifacts.state"; +import {map} from "rxjs/operators"; +import {WorkspaceState} from "../../../store/states/workspace.state"; +import {ArtifactModel} from "../../../../models/artifacts"; + +@Component({ + selector: 'information-artifact-page', + templateUrl: './information-artifact-page.component.html', + styleUrls: ['./information-artifact-page.component.less', '../../../../../assets/styles/table-style.less'] +}) +export class InformationArtifactPageComponent implements OnInit { + + public componentId: string; + public componentType: string; + public informationArtifacts$: Observable; + public informationArtifactsAsButtons$: Observable; + @Select(WorkspaceState.isViewOnly) isViewOnly$: boolean; + @ViewChild('informationArtifactsTable') table: any; + + constructor(private workspaceService: WorkspaceService, + private artifactsService: ArtifactsService, + private store: Store) { + } + + ngOnInit(): void { + this.componentId = this.workspaceService.metadata.uniqueId; + this.componentType = this.workspaceService.metadata.componentType; + + this.store.dispatch(new GetArtifactsByTypeAction({ + componentType: this.componentType, + componentId: this.componentId, + artifactType: ArtifactGroupType.INFORMATION + })); + + let artifacts = this.store.select(ArtifactsState.getArtifactsByType).pipe(map(filterFn => filterFn(ArtifactType.INFORMATION))); + this.informationArtifacts$ = artifacts.pipe(map(artifacts => _.filter(artifacts, (artifact) => { + return artifact.esId; + }))); + + this.informationArtifactsAsButtons$ = artifacts.pipe(map(artifacts => _.filter(artifacts, (artifact) => { + return !artifact.esId; + }))); + } + + onActivate(event) { + if (event.type === 'click') { + this.table.rowDetail.toggleExpandRow(event.row); + } + } + + public addOrUpdateArtifact = (artifact: ArtifactModel, isViewOnly?: boolean) => { + this.artifactsService.openArtifactModal(this.componentId, this.componentType, artifact, ArtifactGroupType.INFORMATION, isViewOnly); + } + + public deleteArtifact = (artifactToDelete) => { + this.artifactsService.deleteArtifact(this.componentType, this.componentId, artifactToDelete) + } + +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/information-artifact/information-artifact-page.module.ts b/catalog-ui/src/app/ng2/pages/workspace/information-artifact/information-artifact-page.module.ts new file mode 100644 index 0000000000..5eb9e5851b --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/information-artifact/information-artifact-page.module.ts @@ -0,0 +1,30 @@ +import {CommonModule} from "@angular/common"; +import {NgModule} from "@angular/core"; +import {SdcUiComponentsModule} from "onap-ui-angular"; +import {NgxDatatableModule} from "@swimlane/ngx-datatable"; +import {UiElementsModule} from "../../../components/ui/ui-elements.module"; +import {InformationArtifactPageComponent} from "./information-artifact-page.component"; +import {ArtifactFormModule} from "../../../components/forms/artifacts-form/artifact-form.module"; +import {ArtifactsService} from "../../../components/forms/artifacts-form/artifacts.service"; + +@NgModule({ + declarations: [ + InformationArtifactPageComponent + ], + imports: [ + CommonModule, + SdcUiComponentsModule, + NgxDatatableModule, + UiElementsModule, + ArtifactFormModule + ], + exports: [ + InformationArtifactPageComponent + ], + entryComponents: [ + InformationArtifactPageComponent + ], + providers:[ArtifactsService] +}) +export class InformationArtifactPageModule { +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/information-artifact/informational-artifact-page.spec.ts b/catalog-ui/src/app/ng2/pages/workspace/information-artifact/informational-artifact-page.spec.ts new file mode 100644 index 0000000000..10fd14739b --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/information-artifact/informational-artifact-page.spec.ts @@ -0,0 +1,77 @@ +import {async, ComponentFixture, TestBed} from "@angular/core/testing"; +import {NO_ERRORS_SCHEMA} from "@angular/core"; +import {ConfigureFn, configureTests} from "../../../../../jest/test-config.helper"; +import {NgxDatatableModule} from "@swimlane/ngx-datatable"; +import {WorkspaceService} from "../workspace.service"; +import {SdcUiServices} from "onap-ui-angular"; +import {TopologyTemplateService} from "../../../services/component-services/topology-template.service"; +import {Observable} from "rxjs/Observable"; +import {ComponentMetadata} from "../../../../models/component-metadata"; +import 'rxjs/add/observable/of'; +import {NgxsModule, Store} from "@ngxs/store"; +import {ArtifactsState} from "../../../store/states/artifacts.state"; +import {InformationArtifactPageComponent} from "./information-artifact-page.component"; +import { informationalArtifactsMock} from "../../../../../jest/mocks/artifacts-mock"; +import {ArtifactsService} from "../../../components/forms/artifacts-form/artifacts.service"; + +describe('informational artifacts page', () => { + + let fixture: ComponentFixture; + let topologyTemplateServiceMock: Partial; + let workspaceServiceMock: Partial; + let loaderServiceMock: Partial; + let store: Store; + + beforeEach( + async(() => { + + topologyTemplateServiceMock = { + getArtifactsByType: jest.fn().mockImplementation((componentType, id, artifactType) => Observable.of(informationalArtifactsMock)) + }; + workspaceServiceMock = {metadata: {uniqueId: 'service_unique_id', componentType: 'SERVICE'}} + + loaderServiceMock = { + activate : jest.fn(), + deactivate: jest.fn() + } + const configure: ConfigureFn = testBed => { + testBed.configureTestingModule({ + declarations: [InformationArtifactPageComponent], + imports: [NgxDatatableModule, NgxsModule.forRoot([ArtifactsState])], + schemas: [NO_ERRORS_SCHEMA], + providers: [ + {provide: WorkspaceService, useValue: workspaceServiceMock}, + {provide: TopologyTemplateService, useValue: topologyTemplateServiceMock}, + {provide: SdcUiServices.LoaderService, useValue: loaderServiceMock }, + {provide: ArtifactsService, useValue: {}}, + ], + }); + }; + + configureTests(configure).then(testBed => { + fixture = testBed.createComponent(InformationArtifactPageComponent); + store = testBed.get(Store); + }); + }) + ); + + it('should match current snapshot of informational artifact pages component', () => { + expect(fixture).toMatchSnapshot(); + }); + + it('should see exactly 3 informational artifacts and six buttons to add artifact by template', () => { + fixture.componentInstance.ngOnInit(); + fixture.componentInstance.informationArtifacts$.subscribe((artifacts)=> { + expect(artifacts.length).toEqual(3); + }) + fixture.componentInstance.informationArtifactsAsButtons$.subscribe((artifacts)=> { + expect(artifacts.length).toEqual(6); + }) + + store.selectOnce(state => state.artifacts.artifacts).subscribe(artifacts => { + expect(artifacts.length).toEqual(9); + }); + }) + + +}); \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.html b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.html new file mode 100644 index 0000000000..f496e64c17 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.html @@ -0,0 +1,22 @@ +
+ + + + {{row[column.prop]}} + + + {{row[column.prop].property.type}} + + + {{row[column.prop]}} + + + +
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.less b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.less new file mode 100644 index 0000000000..007f509538 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.less @@ -0,0 +1,9 @@ + +:host ::ng-deep { + .ngx-datatable { + > div { + min-height: auto !important; + } + + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.ts new file mode 100644 index 0000000000..2a1a16e265 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities-properties/capabilities-properties.ts @@ -0,0 +1,33 @@ + +import { ViewChild, Input, OnInit, Component } from "@angular/core"; +import {SdcUiServices} from "onap-ui-angular"; +import { ModalsHandler } from "../../../../../../utils/modals-handler"; +import { WorkspaceService } from "../../../workspace.service"; +import { PropertyModel } from "../../../../../../models/properties"; + + +@Component({ + selector: 'capabilities-properties', + templateUrl: './capabilities-properties.html', + styleUrls: ['./capabilities-properties.less', '../../../../../../../assets/styles/table-style.less'] +}) +export class CapabilitiesPropertiesComponent { + @Input() public capabilitiesProperties: Array = []; + + private capabilityPropertiesColumns = [ + {name: 'Name', prop: 'name', flexGrow: 1}, + {name: 'Type', prop: 'type', flexGrow: 1}, + {name: 'Schema', prop: 'schema', flexGrow: 1}, + {name: 'Description', prop: 'description', flexGrow: 1}, + ]; + constructor(private modalsHandler: ModalsHandler, + private workspaceService: WorkspaceService) {} + + private updateProperty(property: PropertyModel): void { + _.forEach(this.capabilitiesProperties, (prop: PropertyModel) => { + prop.readonly = true; + }); + this.modalsHandler.openEditPropertyModal(property, this.workspaceService.metadata, this.capabilitiesProperties, false, 'component', + this.workspaceService.metadata.uniqueId); + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.html b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.html new file mode 100644 index 0000000000..819eb84849 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.html @@ -0,0 +1,59 @@ +
+
+ + + + +
+ + + +
Properties
+ +
+
+ + +
+ + {{row.name}} +
+
+
+ + + {{row.type ? row.type.replace("tosca.capabilities.",""): ''}} + + + + + {{row.description}} + + + + + + {{row.validSourceTypes ? row.validSourceTypes.join(','): ''}} + + + + + + {{row.minOccurrences}},{{row.maxOccurrences}} + + +
+
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.less b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.less new file mode 100644 index 0000000000..0c520a8135 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.less @@ -0,0 +1,16 @@ +:host ::ng-deep { + .datatable-row-detail { + width: 1260px; + } + .datatable-body-row { + cursor: pointer; + } +} +.expand-collapse-all-rows { + position: absolute; + top: 172px; + left: 890px; +} +.properties-title { + padding-bottom: 10px; +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.ts new file mode 100644 index 0000000000..02db5d3aee --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilities.component.ts @@ -0,0 +1,79 @@ +import {Capability, CapabilityUI} from "../../../../../models/capability"; +import { ViewChild, Input, OnInit, Component } from "@angular/core"; +import {SdcUiServices} from "onap-ui-angular"; +import {CapabilitiesEditorComponent} from "./capabilityEditor/capabilities-editor.component"; +import {WorkspaceService} from "../../workspace.service"; +import {TopologyTemplateService} from "../../../../services/component-services/topology-template.service"; +import {ReqAndCapabilitiesService} from "../req-and-capabilities.service"; +import {ModalComponent} from "onap-ui-angular/dist/modals/modal.component"; +import {EventListenerService} from "../../../../../services/event-listener-service"; + + +@Component({ + selector: 'capabilities', + templateUrl: './capabilities.component.html', + styleUrls: ['./capabilities.component.less','../../../../../../assets/styles/table-style.less'] +}) +export class CapabilitiesComponent { + @Input() public capabilities: Array; + @ViewChild('capabilitiesTable') capabilitiesTable: any; + private customModalInstance: ModalComponent; + + constructor( + private workspaceService: WorkspaceService, + private loaderService: SdcUiServices.LoaderService, + private topologyTemplateService: TopologyTemplateService, + private reqAndCapabilitiesService : ReqAndCapabilitiesService, + private modalService: SdcUiServices.ModalService, + private eventListenerService: EventListenerService) { + } + + private onSelectCapabilities({ selected }) { + } + + editCapability(cap: CapabilityUI) { + let modalConfig = { + size: 'md', + title: 'Update Capability', + type: 'custom', + buttons: [ + { + id: 'saveButton', + text: ('Update'), + size: "'x-small'", + callback: () => this.updateCapability(), + closeModal: true + }, + {text: "Cancel", size: "'x-small'", closeModal: true}] + }; + let modalInputs = { + capability: cap, + capabilityTypesList: this.reqAndCapabilitiesService.getCapabilityTypesList(), + }; + + this.customModalInstance = this.modalService.openCustomModal(modalConfig, CapabilitiesEditorComponent, {input: modalInputs}); + this.customModalInstance.innerModalContent.instance. + onValidationChange.subscribe((isValid) => this.customModalInstance.getButtonById('saveButton').disabled = !isValid); + } + + expendRow(row) { + this.capabilitiesTable.rowDetail.toggleExpandRow(row); + } + + private updateCapability() { + const capability = this.customModalInstance.innerModalContent.instance.capabilityData; + this.loaderService.activate(); + if (capability.uniqueId) { + this.topologyTemplateService.updateCapability(this.workspaceService.metadata.getTypeUrl(), this.workspaceService.metadata.uniqueId, capability).subscribe((result) => { + let index = this.capabilities.findIndex((cap) => result[0].uniqueId === cap.uniqueId); + this.capabilities[index] = new CapabilityUI(result[0], this.workspaceService.metadata.uniqueId); + this.loaderService.deactivate(); + this.eventListenerService.notifyObservers('CAPABILITIES_UPDATED'); + }, () => { + this.loaderService.deactivate(); + }); + } + } + + +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.html b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.html new file mode 100644 index 0000000000..bc15d4d228 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.html @@ -0,0 +1,93 @@ +
+
+
+
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + + + + +
+
+
+
+
+
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.less b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.less new file mode 100644 index 0000000000..324dc6c4d2 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.less @@ -0,0 +1,38 @@ +@import '../../../../../../../assets/styles/variables.less'; + +.capability-editor { + .i-sdc-form-content-capability-content { + padding: 10px 25px; + .group-with-border { + margin: 25px 0; + padding: 15px 0; + border-top: 1px solid @tlv_color_u; + border-bottom: 1px solid @tlv_color_u; + .content-row:not(:last-of-type) { + padding-bottom: 13px; + } + } + + .occurrences-label { + font-family: @font-opensans-bold; + margin-bottom: 19px; + } + .occurrences-section, /deep/ .max-occurrences-value { + display: flex; + .min-occurrences-value { + padding-right: 30px; + } + .unbounded-value { + padding-top: 7px; + padding-right: 20px; + .sdc-checkbox__label { + text-transform: capitalize; + } + } + } + textarea { + min-height: unset; + height: unset; + } + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.ts new file mode 100644 index 0000000000..3bafa42e0f --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.component.ts @@ -0,0 +1,81 @@ +import {Component} from '@angular/core'; +import {ServiceServiceNg2} from "app/ng2/services/component-services/service.service"; +import {Capability, CapabilityTypeModel} from 'app/models'; +import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component"; +import {TranslateService} from 'app/ng2/shared/translator/translate.service'; +import {Subject} from "rxjs"; + +@Component({ + selector: 'capabilities-editor', + templateUrl: './capabilities-editor.component.html', + styleUrls: ['./capabilities-editor.component.less'], + providers: [ServiceServiceNg2] +}) + +export class CapabilitiesEditorComponent { + input: { + test: string, + capability: Capability, + capabilityTypesList: Array, + isReadonly: boolean; + }; + capabilityData: Capability; + capabilityTypesMappedList: Array; + isUnboundedChecked: boolean; + isReadonly: boolean; + translatedUnboundTxt: string; + + public onValidationChange: Subject = new Subject(); + + constructor(private translateService: TranslateService) { + } + + ngOnInit() { + this.capabilityData = new Capability(this.input.capability); + this.translatedUnboundTxt = ''; + this.capabilityData.minOccurrences = this.capabilityData.minOccurrences || 0; + this.translateService.languageChangedObservable.subscribe(lang => { + this.translatedUnboundTxt = this.translateService.translate('REQ_CAP_OCCURRENCES_UNBOUNDED'); + this.capabilityData.maxOccurrences = this.capabilityData.maxOccurrences || this.translatedUnboundTxt; + this.isUnboundedChecked = this.capabilityData.maxOccurrences === this.translatedUnboundTxt; + }); + this.capabilityTypesMappedList = _.map(this.input.capabilityTypesList, capType => new DropdownValue(capType.toscaPresentation.type, capType.toscaPresentation.type)); + this.isReadonly = this.input.isReadonly; + this.validityChanged(); + } + + onUnboundedChanged() { + this.isUnboundedChecked = !this.isUnboundedChecked; + this.capabilityData.maxOccurrences = this.isUnboundedChecked ? this.translatedUnboundTxt : null; + this.validityChanged(); + } + + checkFormValidForSubmit() { + return this.capabilityData.name && this.capabilityData.name.length && + this.capabilityData.type && this.capabilityData.type.length && !_.isEqual(this.capabilityData.minOccurrences, "") && this.capabilityData.minOccurrences >= 0 && + ( + this.isUnboundedChecked || + (this.capabilityData.maxOccurrences && (this.capabilityData.minOccurrences <= parseInt(this.capabilityData.maxOccurrences))) + ); + } + + onSelectCapabilityType(selectedCapType: DropdownValue) { + this.capabilityData.type = selectedCapType && selectedCapType.value; + if (selectedCapType && selectedCapType.value) { + let selectedCapabilityTypeObj: CapabilityTypeModel = this.input.capabilityTypesList.find(capType => capType.toscaPresentation.type === selectedCapType.value); + this.capabilityData.description = selectedCapabilityTypeObj.toscaPresentation.description; + this.capabilityData.validSourceTypes = selectedCapabilityTypeObj.toscaPresentation.validTargetTypes; + this.capabilityData.properties = _.forEach( + _.toArray(selectedCapabilityTypeObj.properties), + prop => prop.uniqueId = null //a requirement for the BE + ); + } + this.validityChanged(); + } + + validityChanged = () => { + let validState = this.checkFormValidForSubmit(); + this.onValidationChange.next(validState); + } + +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.module.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.module.ts new file mode 100644 index 0000000000..38b104a0f6 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/capabilities/capabilityEditor/capabilities-editor.module.ts @@ -0,0 +1,29 @@ +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {CapabilitiesEditorComponent} from './capabilities-editor.component'; +import {FormsModule} from '@angular/forms'; +import {FormElementsModule} from 'app/ng2/components/ui/form-components/form-elements.module'; +import {UiElementsModule} from 'app/ng2/components/ui/ui-elements.module'; +import {TranslateModule} from 'app/ng2/shared/translator/translate.module'; +import {SdcUiComponentsModule} from 'onap-ui-angular'; +// import {SdcUiComponentsModule} from "sdc-ui/lib/angular/index"; + +@NgModule({ + declarations: [ + CapabilitiesEditorComponent + ], + imports: [CommonModule, + FormsModule, + FormElementsModule, + UiElementsModule, + TranslateModule, + SdcUiComponentsModule + ], + exports: [], + entryComponents: [ + CapabilitiesEditorComponent + ], + providers: [] +}) +export class CapabilitiesEditorModule { +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.html b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.html new file mode 100644 index 0000000000..73e0ae52ae --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.html @@ -0,0 +1,21 @@ +
+
+ Add Requirement + Add Capability + + + + +
+ + +
+
+ +
+
+
+
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.less b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.less new file mode 100644 index 0000000000..f3d39cacd6 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.less @@ -0,0 +1,19 @@ +.req-and-cap-filter { + width: 336px; + float: right; + margin-right: 10px; +} + +.addTitle { + float: right; + text-transform: uppercase; + font-family: OpenSans-Semibold, sans-serif; + color: #009fdb; + cursor: pointer; +} + +:host ::ng-deep .sdc-tabs { + .sdc-tab-content { + margin-top: 0; + } +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.spec.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.spec.ts new file mode 100644 index 0000000000..b7fad045d3 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.spec.ts @@ -0,0 +1,127 @@ +import {async, ComponentFixture, TestBed} from "@angular/core/testing"; +import { NO_ERRORS_SCHEMA} from "@angular/core"; +import {ConfigureFn, configureTests} from "../../../../../jest/test-config.helper"; + +import {Observable} from "rxjs/Observable"; +import {NgxDatatableModule} from "@swimlane/ngx-datatable"; +import {SdcUiServices, SdcUiCommon} from "onap-ui-angular"; +import 'rxjs/add/observable/of'; +import {ReqAndCapabilitiesComponent} from "./req-and-capabilities.component"; +import {ReqAndCapabilitiesService} from "./req-and-capabilities.service"; +import {WorkspaceService} from "../workspace.service"; +import { + capabilitiesMock, + filterRequirmentsMock, + requirementMock +} from "../../../../../jest/mocks/req-and-capabilities.mock"; +import {ComponentMetadata} from "../../../../models/component-metadata"; +import { TopologyTemplateService } from "../../../services/component-services/topology-template.service"; +import {EventListenerService} from "../../../../services/event-listener-service"; + +describe('req and capabilities component', () => { + + let fixture: ComponentFixture; + let workspaceServiceMock: Partial; + let loaderServiceMock: Partial; + let topologyTemplateServiceMock: Partial; + let createDynamicComponentServiceMock: Partial + let reqAndCapabilitiesService: Partial; + let modalService: Partial; + let eventListenerService: Partial; + + + + beforeEach( + async(() => { + + workspaceServiceMock = { + metadata: new ComponentMetadata() + }; + + topologyTemplateServiceMock = { + getRequirementsAndCapabilitiesWithProperties: jest.fn().mockImplementation(() => + Observable.of({requirements: {'tosca.requirements.Node': requirementMock}, + capabilities: {'tosca.capabilities.Node': capabilitiesMock}})) + }; + + loaderServiceMock = { + activate : jest.fn(), + deactivate: jest.fn() + } + createDynamicComponentServiceMock = { + insertComponentDynamically: jest.fn() + } + + const configure: ConfigureFn = testBed => { + testBed.configureTestingModule({ + declarations: [ReqAndCapabilitiesComponent], + imports: [NgxDatatableModule], + schemas: [NO_ERRORS_SCHEMA], + providers: [ + { provide: WorkspaceService, useValue: workspaceServiceMock }, + { provide: SdcUiServices.LoaderService, useValue: loaderServiceMock }, + { provide: TopologyTemplateService, useValue: topologyTemplateServiceMock }, + { provide: SdcUiServices.CreateDynamicComponentService, useValue: createDynamicComponentServiceMock }, + { provide: ReqAndCapabilitiesService, useValue: reqAndCapabilitiesService }, + { provide: SdcUiServices.ModalService, useValue: modalService }, + { provide: EventListenerService, useValue: eventListenerService } + ], + }); + }; + configureTests(configure).then(testBed => { + fixture = testBed.createComponent(ReqAndCapabilitiesComponent); + }); + }) + ); + + it('should see exactly 2 requirement in requirements table when call initCapabilitiesAndRequirements and meta data requirements null', () => { + workspaceServiceMock.metadata.requirements = null; + fixture.componentInstance.initCapabilitiesAndRequirements(); + expect(workspaceServiceMock.metadata.requirements["tosca.requirements.Node"].length).toBe(3); + }); + it('should see exactly 2 capabilities in capabilities table when call initCapabilitiesAndRequirements and meta data capabilities null', () => { + workspaceServiceMock.metadata.capabilities = null; + fixture.componentInstance.initCapabilitiesAndRequirements(); + expect(workspaceServiceMock.metadata.capabilities["tosca.capabilities.Node"].length).toBe(2); + }); + + it('capabilities array papulated when call populateReqOrCap with capabilities', () => { + workspaceServiceMock.metadata.capabilities = {"tosca.capabilities.Node": capabilitiesMock, "tosca.capabilities.Scalable": capabilitiesMock}; + fixture.componentInstance.populateReqOrCap("capabilities"); + expect(fixture.componentInstance.capabilities.length).toBe(4); + }); + + it('create requirements component when call loadReqOrCap with true', () => { + createDynamicComponentServiceMock.insertComponentDynamically.mockImplementation(() => { return {instance: {requirements: requirementMock}}}); + fixture.componentInstance.requirements = requirementMock; + fixture.componentInstance.loadReqOrCap(true); + expect(fixture.componentInstance.instanceRef.instance.requirements.length).toEqual(3); + }); + + it('create capabilities component when call loadReqOrCap with false', () => { + fixture.componentInstance.instanceRef = {instance: {requirements: null}}; + createDynamicComponentServiceMock.insertComponentDynamically.mockImplementation(() => { return {instance: {capabilities: capabilitiesMock}}}); + fixture.componentInstance.capabilities = capabilitiesMock; + fixture.componentInstance.requirementsUI = filterRequirmentsMock; + let event = { + target : { + value : 'root' + } + } + fixture.componentInstance.updateFilter(event); + expect(fixture.componentInstance.instanceRef.instance.requirements.length).toBe(1); + }); + + it('should filter 1 capabilities when searching and call updateFilter function and instanceRef is capabilities component', () => { + fixture.componentInstance.instanceRef = {instance: {capabilities: null}}; + fixture.componentInstance.capabilities = capabilitiesMock; + fixture.componentInstance.selectTabName = 'CAPABILITIES'; + let event = { + target : { + value : '1source' + } + } + fixture.componentInstance.updateFilter(event); + expect(fixture.componentInstance.instanceRef.instance.capabilities[0].type).toBe("tosca.capabilities.Node"); + }); +}); diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.ts new file mode 100644 index 0000000000..69999bfb86 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.component.ts @@ -0,0 +1,229 @@ +import { Component, ComponentRef, OnInit, ViewChild, ViewContainerRef } from '@angular/core'; +import * as _ from 'lodash'; +import { SdcUiServices } from 'onap-ui-angular'; +import { Capability, CapabilityUI } from '../../../../models/capability'; +import { Requirement, RequirementUI } from '../../../../models/requirement'; +import { TopologyTemplateService } from '../../../services/component-services/topology-template.service'; +import { ComponentGenericResponse } from '../../../services/responses/component-generic-response'; +import { WorkspaceService } from '../workspace.service'; +import { CapabilitiesComponent } from './capabilities/capabilities.component'; +import { RequirmentsComponent } from './requirements/requirments.components'; +import {ReqAndCapabilitiesService} from "./req-and-capabilities.service"; +import {CapabilitiesEditorComponent} from "./capabilities/capabilityEditor/capabilities-editor.component"; +import {ModalComponent} from "onap-ui-angular/dist/modals/modal.component"; +import {EventListenerService} from "../../../../services/event-listener-service"; +import {RequirementsEditorComponent} from "./requirements/requirementEditor/requirements-editor.component"; + +@Component({ + selector: 'req-and-capabilities', + templateUrl: './req-and-capabilities.component.html', + styleUrls: ['./req-and-capabilities.component.less'] +}) +export class ReqAndCapabilitiesComponent implements OnInit { + + @ViewChild('requirmentsContainer', { read: ViewContainerRef }) requirmentsContainer: ViewContainerRef; + @ViewChild('capabilitiesContainer', { read: ViewContainerRef }) capabilitiesContainer: ViewContainerRef; + private requirements: Requirement[] = []; + private requirementsUI: RequirementUI[] = []; + private capabilities: Capability[] = []; + private selectTabName: string = 'REQUIREMENTS'; + private notEmptyTable: boolean = true; + private instanceRef: ComponentRef; + private customModalInstance: ModalComponent; + readonly INPUTS_FOR_CAPABILITIES: string = 'INPUTS_FOR_CAPABILITIES'; + readonly INPUTS_FOR_REQUIREMENTS: string = 'INPUTS_FOR_REQUIREMENTS'; + + constructor(private workspaceService: WorkspaceService, + private loaderService: SdcUiServices.LoaderService, + private topologyTemplateService: TopologyTemplateService, + private createDynamicComponentService: SdcUiServices.CreateDynamicComponentService, + private reqAndCapabilitiesService : ReqAndCapabilitiesService, + private modalService: SdcUiServices.ModalService, + private eventListenerService: EventListenerService) { + } + + ngOnInit(): void { + this.initCapabilitiesAndRequirements(); + + this.eventListenerService.registerObserverCallback('CAPABILITIES_UPDATED', () => { + this.loadReqOrCap(); + }); + + this.eventListenerService.registerObserverCallback('REQUIREMENTS_UPDATED', () => { + this.loadReqOrCap(); + }); + } + + + + private initCapabilitiesAndRequirements(): void { + if (!this.workspaceService.metadata.capabilities || !this.workspaceService.metadata.requirements) { + this.loaderService.activate(); + this.topologyTemplateService.getRequirementsAndCapabilitiesWithProperties + (this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId) + .subscribe((response: ComponentGenericResponse) => { + this.workspaceService.metadata.capabilities = response.capabilities; + this.workspaceService.metadata.requirements = response.requirements; + this.initReqOrCap(); + this.loaderService.deactivate(); + }, (error) => { + this.loaderService.deactivate(); + }); + } else { + this.initReqOrCap(); + } + } + + private initReqOrCap() { + this.populateReqOrCap('requirements'); + this.extendRequirementsToRequiremnetsUI(this.requirements); + this.populateReqOrCap('capabilities'); + this.loadReqOrCap(); + } + + private populateReqOrCap(instanceName: string) { + _.forEach(this.workspaceService.metadata[instanceName], (concatArray: any[], name) => { + this[instanceName] = this[instanceName].concat(concatArray); + }); + } + + private updateFilter(event) { + const val = event.target.value.toLowerCase(); + if (this.selectTabName === 'REQUIREMENTS') { + this.instanceRef.instance.requirements = this.requirementsUI.filter((req: Requirement) => { + return !val || this.filterRequirments(req, val); + }); + } else { + this.instanceRef.instance.capabilities = this.capabilities.filter((cap: Capability) => { + return !val || this.filterCapabilities(cap, val); + }); + } + + } + + private selectTab($event) { + this.selectTabName = $event.title.contains('Requirement') ? 'REQUIREMENTS' : 'CATPABILITIES'; + this.loadReqOrCap(); + } + + private async loadReqOrCap() { + if (this.instanceRef) { + this.instanceRef.destroy(); + } + + if (this.selectTabName === 'REQUIREMENTS') { + this.notEmptyTable = this.requirementsUI.length !== 0; + this.instanceRef = this.createDynamicComponentService. + insertComponentDynamically(RequirmentsComponent, {requirements: this.requirementsUI}, this.requirmentsContainer); + // TODO - Keep the initInputs, so it will be called only for the first time - no need to wait to thse API's every time that a user switches tab + await this.reqAndCapabilitiesService.initInputs(this.INPUTS_FOR_REQUIREMENTS); + } else { + this.notEmptyTable = this.capabilities.length !== 0; + this.instanceRef = this.createDynamicComponentService. + insertComponentDynamically(CapabilitiesComponent, {capabilities: this.capabilities}, this.capabilitiesContainer); + // TODO - Keep the initInputs, so it will be called only for the first time - no need to wait to thse API's every time that a user switches tab + await this.reqAndCapabilitiesService.initInputs(this.INPUTS_FOR_CAPABILITIES); + } + } + + private filterCapabilities(capability: Capability, val: string): boolean { + return _.includes([capability.name, capability.description, capability.validSourceTypes.join(), + capability.minOccurrences, capability.maxOccurrences].join('').toLowerCase(), val) || + (capability.type && capability.type.replace('tosca.capabilities.', '').toLowerCase().indexOf(val) !== -1); + } + + private filterRequirments(requirement: Requirement, val: string): boolean { + return _.includes([requirement.name, requirement.minOccurrences, requirement.maxOccurrences].join('').toLowerCase(), val) || + (requirement.capability && requirement.capability.substring('tosca.capabilities.'.length).toLowerCase().indexOf(val) !== -1) || + (requirement.node && requirement.node.substring('tosca.node.'.length).toLowerCase().indexOf(val) !== -1) || + (requirement.relationship && requirement.relationship.substring('tosca.relationship.'.length) + .toLowerCase().indexOf(val) !== -1); + } + + private addCapability() { + let modalConfig = { + size: 'md', + title: 'Add Capability', + type: 'custom', + buttons: [ + { + id: 'saveButton', + text: ('Create'), + size: "'x-small'", + callback: () => this.createCapability(), + closeModal: true + }, + {text: "Cancel", size: "'x-small'", closeModal: true}] + }; + let modalInputs = { + capabilityTypesList: this.reqAndCapabilitiesService.getCapabilityTypesList(), + }; + + this.customModalInstance = this.modalService.openCustomModal(modalConfig, CapabilitiesEditorComponent, {input: modalInputs}); + this.customModalInstance.innerModalContent.instance. + onValidationChange.subscribe((isValid) => this.customModalInstance.getButtonById('saveButton').disabled = !isValid); + } + + private createCapability() { + const capability = this.customModalInstance.innerModalContent.instance.capabilityData; + this.loaderService.activate(); + if (!capability.uniqueId) { + this.topologyTemplateService.createCapability(this.workspaceService.metadata.getTypeUrl(), this.workspaceService.metadata.uniqueId, capability).subscribe((result) => { + this.capabilities.unshift(new CapabilityUI(result[0], this.workspaceService.metadata.uniqueId)); + this.loadReqOrCap(); + this.loaderService.deactivate(); + }, () => { + this.loaderService.deactivate(); + }); + } + } + + private addRequiremnet () { + let modalConfig = { + size: 'md', + title: 'Add Requirement', + type: 'custom', + buttons: [ + { + id: 'saveButton', + text: ('Create'), + size: "'x-small'", + callback: () => this.createRequirement(), + closeModal: true + }, + {text: "Cancel", size: "'x-small'", closeModal: true}] + }; + let modalInputs = { + // requirement: req, + relationshipTypesList: this.reqAndCapabilitiesService.getRelationsShipeTypeList(), + nodeTypesList: this.reqAndCapabilitiesService.getNodeTypesList(), + capabilityTypesList: this.reqAndCapabilitiesService.getCapabilityTypesList(), + // isReadonly: this.$scope.isViewMode() || !this.$scope.isDesigner(), + }; + + this.customModalInstance = this.modalService.openCustomModal(modalConfig, RequirementsEditorComponent, {input: modalInputs}); + this.customModalInstance.innerModalContent.instance. + onValidationChange.subscribe((isValid) => this.customModalInstance.getButtonById('saveButton').disabled = !isValid); + } + + + private createRequirement() { + const requirement = this.customModalInstance.innerModalContent.instance.requirementData; + this.loaderService.activate(); + if (!requirement.uniqueId) { + this.topologyTemplateService.createRequirement(this.workspaceService.metadata.getTypeUrl(), this.workspaceService.metadata.uniqueId, requirement).subscribe(result => { + this.requirementsUI.unshift(new RequirementUI(result[0], this.workspaceService.metadata.uniqueId)); + this.loadReqOrCap(); + this.loaderService.deactivate(); + }, () => { + this.loaderService.deactivate(); + }); + } + } + + private extendRequirementsToRequiremnetsUI(requirements: Requirement[]) { + this.requirements.map((requirement) => { + this.requirementsUI.push(new RequirementUI(requirement, this.workspaceService.metadata.uniqueId)); + }); + } +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.module.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.module.ts new file mode 100644 index 0000000000..aacb3a5bd1 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.module.ts @@ -0,0 +1,49 @@ +import {NgModule} from "@angular/core"; +import {SdcUiComponentsModule} from "onap-ui-angular"; + +import {NgxDatatableModule} from "@swimlane/ngx-datatable"; +import { ReqAndCapabilitiesComponent } from "./req-and-capabilities.component"; +import { CommonModule } from "@angular/common"; + +import {RequirmentsComponent } from "./requirements/requirments.components"; +import { CapabilitiesComponent } from "./capabilities/capabilities.component"; +import { CapabilitiesPropertiesComponent } from "./capabilities/capabilities-properties/capabilities-properties"; +import {ReqAndCapabilitiesService} from "./req-and-capabilities.service"; +import {RequirementsEditorComponent} from "./requirements/requirementEditor/requirements-editor.component"; +import {CapabilitiesEditorComponent} from "./capabilities/capabilityEditor/capabilities-editor.component"; +import {TranslateModule} from "../../../shared/translator/translate.module"; +import {ToscaTypesServiceNg2} from "../../../services/tosca-types.service"; + +@NgModule({ + declarations: [ + ReqAndCapabilitiesComponent, + CapabilitiesComponent, + RequirmentsComponent, + CapabilitiesPropertiesComponent, + RequirementsEditorComponent, + CapabilitiesEditorComponent + ], + imports: [ + CommonModule, + SdcUiComponentsModule, + NgxDatatableModule, + TranslateModule + ], + exports: [ + ReqAndCapabilitiesComponent, + CapabilitiesComponent, + RequirmentsComponent, + CapabilitiesPropertiesComponent + ], + entryComponents: [ + ReqAndCapabilitiesComponent, + CapabilitiesComponent, + RequirmentsComponent, + CapabilitiesPropertiesComponent, + RequirementsEditorComponent, + CapabilitiesEditorComponent + ], + providers: [ ReqAndCapabilitiesService] +}) +export class reqAndCapabilitiesModule { +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.service.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.service.ts new file mode 100644 index 0000000000..470aac75a6 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/req-and-capabilities.service.ts @@ -0,0 +1,80 @@ +import { Injectable } from "@angular/core"; +import { TopologyTemplateService } from "../../../services/component-services/topology-template.service"; +import { Store } from "@ngxs/store"; +import { SdcUiServices } from "onap-ui-angular"; +import { CapabilityTypeModel } from "../../../../models/capability-types"; +import { RelationshipTypeModel } from "../../../../models/relationship-types"; +import { NodeTypeModel } from "../../../../models/node-types"; +import { WorkspaceService } from "../workspace.service"; +import { ToscaTypesServiceNg2 } from "../../../services/tosca-types.service"; + + + +@Injectable() +export class ReqAndCapabilitiesService { + + private capabilityTypesList: CapabilityTypeModel[]; + private relationshipTypesList: RelationshipTypeModel[]; + private nodeTypesList: NodeTypeModel[]; + private capabilitiesListUpdated: boolean = false; + private requirementsListUpdated: boolean = false; + private nodeTypeListUpdated: boolean = false; + + readonly INPUTS_FOR_REQUIREMENTS: string = 'INPUTS_FOR_REQUIREMENTS'; + readonly INPUTS_FOR_CAPABILITIES: string = 'INPUTS_FOR_CAPABILITIES'; + + constructor( + private workspaceService: WorkspaceService, + private modalService: SdcUiServices.ModalService, + private loaderService: SdcUiServices.LoaderService, + private topologyTemplateService: TopologyTemplateService, + private store: Store, + private toscaTypesServiceNg2: ToscaTypesServiceNg2){} + + public isViewOnly = (): boolean => { + return this.store.selectSnapshot((state) => state.workspace.isViewOnly); + } + + public isDesigner = (): boolean => { + return this.store.selectSnapshot((state) => state.workspace.isDesigner); + } + + public async initInputs(initInputsFor: string) { + + if (!this.capabilitiesListUpdated){ + // -- COMMON for both -- + this.capabilityTypesList = []; + let capabilityTypesResult = await this.toscaTypesServiceNg2.fetchCapabilityTypes(); + Object.keys(capabilityTypesResult).forEach(key => {this.capabilityTypesList.push(capabilityTypesResult[key])}) + this.capabilitiesListUpdated = true; + } + + if (initInputsFor === 'INPUTS_FOR_REQUIREMENTS') { + if (!this.requirementsListUpdated){ + this.relationshipTypesList = []; + let relationshipTypesResult = await this.toscaTypesServiceNg2.fetchRelationshipTypes(); + Object.keys(relationshipTypesResult).forEach(key => {this.relationshipTypesList.push(relationshipTypesResult[key])}); + this.requirementsListUpdated = true; + } + + if (!this.nodeTypeListUpdated){ + this.nodeTypesList = []; + let nodeTypesResult = await this.toscaTypesServiceNg2.fetchNodeTypes(); + Object.keys(nodeTypesResult).forEach(key => {this.nodeTypesList.push(nodeTypesResult[key])}) + this.nodeTypeListUpdated = true; + } + } + } + + getCapabilityTypesList() { + return this.capabilityTypesList; + } + + getRelationsShipeTypeList() { + return this.relationshipTypesList; + } + + getNodeTypesList() { + return this.nodeTypesList; + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.html b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.html new file mode 100644 index 0000000000..330680d3ed --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.html @@ -0,0 +1,91 @@ +
+
+
+
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + + + +
+ +
+
+
+
+
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.less b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.less new file mode 100644 index 0000000000..6e50eb79f5 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.less @@ -0,0 +1,35 @@ +@import '../../../../../../../assets/styles/variables.less'; + +.requirement-editor { + .i-sdc-form-content-requirement-content { + padding: 10px 25px; + + .group-with-border { + margin: 25px 0; + padding: 15px 0; + border-top: 1px solid @tlv_color_u; + border-bottom: 1px solid @tlv_color_u; + .content-row:not(:last-of-type) { + padding-bottom: 13px; + } + } + + .occurrences-label { + font-family: @font-opensans-bold; + margin-bottom: 19px; + } + .occurrences-section, /deep/ .max-occurrences-value { + display: flex; + .min-occurrences-value { + padding-right: 30px; + } + .unbounded-value { + padding-top: 7px; + padding-right: 20px; + .sdc-checkbox__label { + text-transform: capitalize; + } + } + } + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.ts new file mode 100644 index 0000000000..2c5c96f3da --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.component.ts @@ -0,0 +1,90 @@ +import {Component} from '@angular/core'; +import {ServiceServiceNg2} from "app/ng2/services/component-services/service.service"; +import {Requirement, RelationshipTypeModel, NodeTypeModel, CapabilityTypeModel} from 'app/models'; +import {TranslateService} from 'app/ng2/shared/translator/translate.service'; +import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component"; +import {Subject} from "rxjs"; + +@Component({ + selector: 'requirements-editor', + templateUrl: 'requirements-editor.component.html', + styleUrls: ['requirements-editor.component.less'], + providers: [ServiceServiceNg2, TranslateService] +}) + +export class RequirementsEditorComponent { + + input: { + requirement: Requirement, + relationshipTypesList: Array; + nodeTypesList: Array; + capabilityTypesList: Array; + isReadonly: boolean; + }; + requirementData: Requirement; + capabilityTypesMappedList: Array; + relationshipTypesMappedList: Array; + nodeTypesMappedList: Array; + isUnboundedChecked: boolean; + isReadonly: boolean; + translatedUnboundTxt: string; + + public onValidationChange: Subject = new Subject(); + + constructor(private translateService: TranslateService) { + } + + ngOnInit() { + this.requirementData = new Requirement(this.input.requirement); + this.requirementData.minOccurrences = this.requirementData.minOccurrences || 0; + this.translatedUnboundTxt = ''; + this.capabilityTypesMappedList = _.map(this.input.capabilityTypesList, capType => new DropdownValue(capType.toscaPresentation.type, capType.toscaPresentation.type)); + this.relationshipTypesMappedList = _.map(this.input.relationshipTypesList, rType => new DropdownValue(rType.toscaPresentation.type, rType.toscaPresentation.type)); + this.nodeTypesMappedList = _.map(this.input.nodeTypesList, nodeType => { + return new DropdownValue( + nodeType.componentMetadataDefinition.componentMetadataDataDefinition.toscaResourceName, + nodeType.componentMetadataDefinition.componentMetadataDataDefinition.toscaResourceName) + }); + this.translateService.languageChangedObservable.subscribe(lang => { + this.translatedUnboundTxt = this.translateService.translate('REQ_CAP_OCCURRENCES_UNBOUNDED'); + this.requirementData.maxOccurrences = this.requirementData.maxOccurrences || this.translatedUnboundTxt; + this.isUnboundedChecked = this.requirementData.maxOccurrences === this.translatedUnboundTxt; + }); + this.isReadonly = this.input.isReadonly; + this.validityChanged(); + } + + onUnboundedChanged() { + this.isUnboundedChecked = !this.isUnboundedChecked; + this.requirementData.maxOccurrences = this.isUnboundedChecked ? this.translatedUnboundTxt : null; + this.validityChanged(); + } + + onCapabilityChanged(selectedCapability: DropdownValue) { + this.requirementData.capability = selectedCapability && selectedCapability.value; + this.validityChanged(); + } + + onNodeChanged(selectedNode: DropdownValue) { + this.requirementData.node = selectedNode && selectedNode.value; + } + + onRelationshipChanged(selectedRelationship: DropdownValue) { + this.requirementData.relationship = selectedRelationship && selectedRelationship.value; + } + + checkFormValidForSubmit() { + return this.requirementData.name && this.requirementData.name.length && + this.requirementData.capability && this.requirementData.capability.length && !_.isEqual(this.requirementData.minOccurrences, "") && this.requirementData.minOccurrences >= 0 && + ( + this.isUnboundedChecked || + (this.requirementData.maxOccurrences && (this.requirementData.minOccurrences <= parseInt(this.requirementData.maxOccurrences))) + ); + } + + validityChanged = () => { + let validState = this.checkFormValidForSubmit(); + this.onValidationChange.next(validState); + } + +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.module.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.module.ts new file mode 100644 index 0000000000..b1d8db54aa --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirementEditor/requirements-editor.module.ts @@ -0,0 +1,28 @@ +import {NgModule} from "@angular/core"; +import {CommonModule} from "@angular/common"; +import {RequirementsEditorComponent} from "./requirements-editor.component"; +import {FormsModule} from "@angular/forms"; +// import {FormElementsModule} from "../../../components/ui/form-components/form-elements.module"; +import {TranslateModule} from 'app/ng2/shared/translator/translate.module'; +import {SdcUiComponentsModule} from "onap-ui-angular/"; +import {FormElementsModule} from 'app/ng2/components/ui/form-components/form-elements.module'; +// import {SdcUiComponentsModule} from "sdc-ui/lib/angular/index"; + +@NgModule({ + declarations: [ + RequirementsEditorComponent + ], + imports: [CommonModule, + FormsModule, + FormElementsModule, + TranslateModule, + SdcUiComponentsModule + ], + exports: [], + entryComponents: [ + RequirementsEditorComponent + ], + providers: [] +}) +export class RequirementsEditorModule { +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirements.component.less b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirements.component.less new file mode 100644 index 0000000000..19f1c9b55a --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirements.component.less @@ -0,0 +1,4 @@ +/deep/ .importedFromFile { + background-color: #f8f8f8; + color: #959595; + } \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirments.components.html b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirments.components.html new file mode 100644 index 0000000000..7606ed189a --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirments.components.html @@ -0,0 +1,38 @@ +
+ + + + {{row.name}} + + + + + {{row.capability ? row.capability.substring("tosca.capabilities.".length) : ''}} + + + + + {{row.node ? row.node.substring("tosca.nodes.".length) : ''}} + + + + + {{row.relationship ? row.relationship.substring("tosca.relationships.".length): ''}} + + + + + + + + {{row.minOccurrences}},{{row.maxOccurrences}} + + + +
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirments.components.ts b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirments.components.ts new file mode 100644 index 0000000000..b65489ce4e --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/req-and-capabilities/requirements/requirments.components.ts @@ -0,0 +1,103 @@ +import {Input, Component, OnInit} from "@angular/core"; +import {Requirement, RequirementUI} from "../../../../../models/requirement"; +import {RequirementsEditorComponent} from "./requirementEditor/requirements-editor.component"; +import {WorkspaceService} from "../../workspace.service"; +import {TopologyTemplateService} from "../../../../services/component-services/topology-template.service"; +import {ReqAndCapabilitiesService} from "../req-and-capabilities.service"; +import {EventListenerService} from "../../../../../services/event-listener-service"; +import {ModalComponent} from "onap-ui-angular/dist/modals/modal.component"; +import {SdcUiServices} from "onap-ui-angular"; +import sortedIndexBy = require("lodash/sortedIndexBy"); + +@Component({ + selector: 'requirments', + templateUrl: './requirments.components.html', + styleUrls: ['../../../../../../assets/styles/table-style.less', './requirements.component.less'] +}) + + + +export class RequirmentsComponent implements OnInit { + @Input() public requirements: Array; + private customModalInstance: ModalComponent; + + constructor( + private workspaceService: WorkspaceService, + private loaderService: SdcUiServices.LoaderService, + private topologyTemplateService: TopologyTemplateService, + private reqAndCapabilitiesService : ReqAndCapabilitiesService, + private modalService: SdcUiServices.ModalService, + private eventListenerService: EventListenerService) { + } + + + ngOnInit(): void { + let isCreatedManually: RequirementUI[] = []; + let isImportedFromFile: RequirementUI[] = []; + + isCreatedManually = this.requirements.filter((requirement) => requirement.isCreatedManually); + isImportedFromFile = this.requirements.filter((requirement) => !requirement.isCreatedManually); + + this.requirements = []; + + isCreatedManually.map((requirement) => this.requirements.push(requirement)); + isImportedFromFile.map((requirement) => this.requirements.push(requirement)); + + } + + + + editRequirement(req) { + + let modalConfig = { + size: 'md', + title: 'Update Requirement', + type: 'custom', + buttons: [ + { + id: 'saveButton', + text: ('Update'), + size: "'x-small'", + callback: () => this.updateRequirement(), + closeModal: true + }, + {text: "Cancel", size: "'x-small'", closeModal: true}] + }; + let modalInputs = { + requirement: req, + relationshipTypesList: this.reqAndCapabilitiesService.getRelationsShipeTypeList(), + nodeTypesList: this.reqAndCapabilitiesService.getNodeTypesList(), + capabilityTypesList: this.reqAndCapabilitiesService.getCapabilityTypesList(), + // isReadonly: this.$scope.isViewMode() || !this.$scope.isDesigner(), + }; + + this.customModalInstance = this.modalService.openCustomModal(modalConfig, RequirementsEditorComponent, {input: modalInputs}); + this.customModalInstance.innerModalContent.instance. + onValidationChange.subscribe((isValid) => this.customModalInstance.getButtonById('saveButton').disabled = !isValid); + + } + + private updateRequirement() { + const requirement = this.customModalInstance.innerModalContent.instance.requirementData; + this.loaderService.activate(); + if (requirement.uniqueId) { + this.topologyTemplateService.updateRequirement(this.workspaceService.metadata.getTypeUrl(), this.workspaceService.metadata.uniqueId, requirement).subscribe(result => { + let index = this.requirements.findIndex(req => result[0].uniqueId === req.uniqueId); + this.requirements[index] = new RequirementUI(result[0], this.workspaceService.metadata.uniqueId); + this.eventListenerService.notifyObservers('REQUIREMENTS_UPDATED'); + this.loaderService.deactivate(); + }, () => { + this.loaderService.deactivate(); + }); + } + } + + getRowClass(row) { + if (!row.isCreatedManually) { + return { + 'importedFromFile': true + }; + } + } + +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/__snapshots__/tosca-artifact-page.spec.ts.snap b/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/__snapshots__/tosca-artifact-page.spec.ts.snap new file mode 100644 index 0000000000..14146d51d2 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/__snapshots__/tosca-artifact-page.spec.ts.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`tosca artifacts page should match current snapshot of tosca artifact pages component 1`] = ` + +
+ +
+ + + + + + + + + +
+
+
+
+`; diff --git a/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.component.html b/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.component.html new file mode 100644 index 0000000000..fece92ee37 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.component.html @@ -0,0 +1,50 @@ +
+ + + +
Label: {{row.artifactLabel}}
+
UUID: {{row.artifactUUID}}
+
Description: {{row.description}}
+
+
+ + +
+ + {{row.artifactDisplayName }} +
+
+
+ + + {{row.artifactType}} + + + + + {{ row.artifactVersion }} + + + + +
+ +
+
+
+
+
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.component.less b/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.component.less new file mode 100644 index 0000000000..9c5dd47585 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.component.less @@ -0,0 +1,7 @@ +.tosca-artifact-page { + .download-artifact-button { + text-align: center; + padding-top: 4px; + + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.component.ts b/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.component.ts new file mode 100644 index 0000000000..e74e5db668 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.component.ts @@ -0,0 +1,46 @@ +import {Component, OnInit, ViewChild} from "@angular/core"; +import {WorkspaceService} from "../workspace.service"; +import {SdcUiServices} from "onap-ui-angular"; +import {ArtifactModel} from "../../../../models"; +import {Select, Store} from "@ngxs/store"; +import {WorkspaceState} from "../../../store/states/workspace.state"; +import * as _ from "lodash"; +import {ArtifactGroupType, COMPONENT_FIELDS} from "../../../../utils"; +import {GetArtifactsByTypeAction} from "../../../store/actions/artifacts.action"; +import {Observable} from "rxjs/index"; +import {ArtifactsState} from "../../../store/states/artifacts.state"; +import {ArtifactType} from "../../../../utils/constants"; +import {map} from "rxjs/operators"; + +@Component({ + selector: 'tosca-artifact-page', + + templateUrl: './tosca-artifact-page.component.html', + styleUrls: ['./tosca-artifact-page.component.less', '../../../../../assets/styles/table-style.less'] +}) +export class ToscaArtifactPageComponent implements OnInit { + + @Select(WorkspaceState.isViewOnly) isViewOnly$: boolean; + @ViewChild('toscaArtifactsTable') table: any; + public toscaArtifacts$: Observable; + public componentId: string; + public componentType:string; + + constructor(private serviceLoader: SdcUiServices.LoaderService, private workspaceService: WorkspaceService, private store: Store) { + } + + + ngOnInit(): void { + this.componentId = this.workspaceService.metadata.uniqueId; + this.componentType = this.workspaceService.metadata.componentType; + + this.store.dispatch(new GetArtifactsByTypeAction({componentType:this.componentType, componentId:this.componentId, artifactType:ArtifactGroupType.TOSCA})); + this.toscaArtifacts$ = this.store.select(ArtifactsState.getArtifactsByType).pipe(map(filterFn => filterFn(ArtifactGroupType.TOSCA))); + } + + onActivate(event) { + if(event.type === 'click'){ + this.table.rowDetail.toggleExpandRow(event.row); + } + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.module.ts b/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.module.ts new file mode 100644 index 0000000000..00c7b0b371 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.module.ts @@ -0,0 +1,28 @@ +import {CommonModule} from "@angular/common"; +import {NgModule} from "@angular/core"; +import {SdcUiComponentsModule} from "onap-ui-angular"; +import {GlobalPipesModule} from "../../../pipes/global-pipes.module"; +import {NgxDatatableModule} from "@swimlane/ngx-datatable"; +import {ToscaArtifactPageComponent} from "./tosca-artifact-page.component"; +import {UiElementsModule} from "../../../components/ui/ui-elements.module"; + +@NgModule({ + declarations: [ + ToscaArtifactPageComponent + ], + imports: [ + CommonModule, + SdcUiComponentsModule, + NgxDatatableModule, + UiElementsModule + ], + exports: [ + ToscaArtifactPageComponent + ], + entryComponents: [ + ToscaArtifactPageComponent + ], + +}) +export class ToscaArtifactPageModule { +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.spec.ts b/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.spec.ts new file mode 100644 index 0000000000..af3558e15b --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/tosca-artifacts/tosca-artifact-page.spec.ts @@ -0,0 +1,71 @@ +import {async, ComponentFixture, TestBed} from "@angular/core/testing"; +import {NO_ERRORS_SCHEMA} from "@angular/core"; +import {ToscaArtifactPageComponent} from "./tosca-artifact-page.component"; +import {ConfigureFn, configureTests} from "../../../../../jest/test-config.helper"; +import {NgxDatatableModule} from "@swimlane/ngx-datatable"; +import {WorkspaceService} from "../workspace.service"; +import {SdcUiServices} from "onap-ui-angular"; +import {TopologyTemplateService} from "../../../services/component-services/topology-template.service"; +import {Observable} from "rxjs/Observable"; +import {ComponentMetadata} from "../../../../models/component-metadata"; +import 'rxjs/add/observable/of'; +import {NgxsModule, Store} from "@ngxs/store"; +import {ArtifactsState} from "../../../store/states/artifacts.state"; +import {toscaArtifactMock} from "../../../../../jest/mocks/artifacts-mock"; + +describe('tosca artifacts page', () => { + + let fixture: ComponentFixture; + let topologyTemplateServiceMock: Partial; + let workspaceServiceMock: Partial; + let loaderServiceMock: Partial; + let store: Store; + + + beforeEach( + async(() => { + + topologyTemplateServiceMock = { + getArtifactsByType: jest.fn().mockImplementation((componentType, id, artifactType) => Observable.of(toscaArtifactMock)) + }; + workspaceServiceMock = {metadata: {uniqueId: 'service_unique_id', componentType: 'SERVICE'}} + + loaderServiceMock = { + activate : jest.fn(), + deactivate: jest.fn() + } + const configure: ConfigureFn = testBed => { + testBed.configureTestingModule({ + declarations: [ToscaArtifactPageComponent], + imports: [NgxDatatableModule, NgxsModule.forRoot([ArtifactsState])], + schemas: [NO_ERRORS_SCHEMA], + providers: [ + {provide: WorkspaceService, useValue: workspaceServiceMock}, + {provide: TopologyTemplateService, useValue: topologyTemplateServiceMock}, + {provide: SdcUiServices.LoaderService, useValue: loaderServiceMock } + ], + }); + }; + + configureTests(configure).then(testBed => { + fixture = testBed.createComponent(ToscaArtifactPageComponent); + store = testBed.get(Store); + }); + }) + ); + + it('should match current snapshot of tosca artifact pages component', () => { + expect(fixture).toMatchSnapshot(); + }); + + it('should see exactly 2 tosca artifacts', () => { + fixture.componentInstance.ngOnInit(); + fixture.componentInstance.toscaArtifacts$.subscribe((artifacts)=> { + expect(artifacts.length).toEqual(2); + }) + store.selectOnce(state => state.artifacts.toscaArtifacts).subscribe(artifacts => { + expect(artifacts.length).toEqual(9); + }); + }) + +}); \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/workspace/workspace-ng1-bridge-service.ts b/catalog-ui/src/app/ng2/pages/workspace/workspace-ng1-bridge-service.ts new file mode 100644 index 0000000000..3d93b459a2 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/workspace-ng1-bridge-service.ts @@ -0,0 +1,37 @@ +/** + * Created by ob0695 on 6/24/2018. + */ +/*- + * ============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========================================================= + */ +import {Store} from "@ngxs/store"; +import {Injectable} from "@angular/core"; +import {UpdateIsViewOnly} from "../../store/actions/workspace.action"; + +@Injectable() +export class WorkspaceNg1BridgeService { + + constructor(private store: Store) { + }; + + public updateIsViewOnly = (isViewOnly: boolean):void => { + this.store.dispatch(new UpdateIsViewOnly(isViewOnly)); + } + +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/workspace.component.ts b/catalog-ui/src/app/ng2/pages/workspace/workspace.component.ts new file mode 100644 index 0000000000..a209406a53 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/workspace.component.ts @@ -0,0 +1,3 @@ +/** + * Created by ob0695 on 6/11/2018. + */ diff --git a/catalog-ui/src/app/ng2/pages/workspace/workspace.module.ts b/catalog-ui/src/app/ng2/pages/workspace/workspace.module.ts new file mode 100644 index 0000000000..cb646379d2 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/workspace.module.ts @@ -0,0 +1,50 @@ +/** + * Created by ob0695 on 6/4/2018. + */ +/** + * Created by ob0695 on 6/4/2018. + */ +import {NgModule} from "@angular/core"; +import {CompositionPageModule} from "../composition/composition-page.module"; + +import {NgxsModule} from "@ngxs/store"; +import {TopologyTemplateService} from "../../services/component-services/topology-template.service"; +import {WorkspaceState} from "../../store/states/workspace.state"; +import {WorkspaceService} from "./workspace.service"; +import {DeploymentPageModule} from "./deployment/deployment-page.module"; +import {ToscaArtifactPageModule} from "./tosca-artifacts/tosca-artifact-page.module"; +import {InformationArtifactPageModule} from "./information-artifact/information-artifact-page.module"; +import { reqAndCapabilitiesModule } from "./req-and-capabilities/req-and-capabilities.module"; +import {AttributesModule} from "./attributes/attributes.module"; +import {ArtifactsState} from "../../store/states/artifacts.state"; +import {InstanceArtifactsState} from "../../store/states/instance-artifacts.state"; +import {DeploymentArtifactsPageModule} from "./deployment-artifacts/deployment-artifacts-page.module"; +import { DistributionModule } from './disribution/distribution.module'; +import { ActivityLogModule } from './activity-log/activity-log.module'; + +@NgModule({ + declarations: [], + imports: [ + DeploymentPageModule, + CompositionPageModule, + AttributesModule, + reqAndCapabilitiesModule, + ToscaArtifactPageModule, + DeploymentArtifactsPageModule, + InformationArtifactPageModule, + DistributionModule, + ActivityLogModule, + NgxsModule.forFeature([WorkspaceState, ArtifactsState, InstanceArtifactsState]) + ], + + exports: [], + entryComponents: [], + providers: [TopologyTemplateService, WorkspaceService] +}) + +export class WorkspaceModule { + + constructor() { + + } +} diff --git a/catalog-ui/src/app/ng2/pages/workspace/workspace.service.ts b/catalog-ui/src/app/ng2/pages/workspace/workspace.service.ts new file mode 100644 index 0000000000..9f985016ec --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/workspace/workspace.service.ts @@ -0,0 +1,70 @@ +/** + * Created by ob0695 on 6/5/2018. + */ +/*- + * ============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 rc2122 on 5/23/2017. + */ +import { Injectable } from '@angular/core'; +import {WorkspaceMode, ComponentState, Role} from "../../../utils/constants"; +import {Component as TopologyTemplate, ComponentMetadata} from "app/models"; +import {CacheService} from "../../services/cache.service"; +import {IComponentMetadata} from "../../../models/component-metadata"; +import {ComponentType} from "../../../utils"; + +@Injectable() +export class WorkspaceService { + + public metadata:ComponentMetadata; + + constructor(private cacheService:CacheService) { + + } + + public setComponentMetadata = (metadata: ComponentMetadata) => { + this.metadata = metadata; + } + + public getMetadataType(): string { + switch (this.metadata.componentType) { + case ComponentType.SERVICE: + return ComponentType.SERVICE; + default: + return this.metadata.resourceType; + } + } + + public getComponentMode = (component:TopologyTemplate):WorkspaceMode => {//return if is edit or view for resource or service + let mode = WorkspaceMode.VIEW; + + let user = this.cacheService.get("user"); + if (component.lifecycleState === ComponentState.NOT_CERTIFIED_CHECKOUT && + component.lastUpdaterUserId === user.userId) { + if ((component.isService() || component.isResource()) && user.role == Role.DESIGNER) { + mode = WorkspaceMode.EDIT; + } + } + return mode; + } +} + + \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pipes/entity-filter.pipe.ts b/catalog-ui/src/app/ng2/pipes/entity-filter.pipe.ts new file mode 100644 index 0000000000..af107ed006 --- /dev/null +++ b/catalog-ui/src/app/ng2/pipes/entity-filter.pipe.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========================================================= + */ + +import {Pipe, PipeTransform} from "@angular/core"; +import {Component, Resource} from "app/models"; +import {ComponentType} from "app/utils/constants"; + +export interface ISearchFilter { + [key:string]: string; +} + +export interface IEntityFilterObject { + // Types + selectedComponentTypes?:Array; + selectedResourceSubTypes?:Array; + // Categories + selectedCategoriesModel?:Array; + // Statuses + selectedStatuses?:Array; + // distributed + distributed?:Array; + // search + search?:ISearchFilter; + +} + +@Pipe({name: 'entity-filter'}) +export class EntityFilterPipe implements PipeTransform{ + constructor() { + } + + public static transform(components:Array, filter:IEntityFilterObject) { + let filteredComponents:Array = components; + + // filter by type + // -------------------------------------------------------------------------- + if ((filter.selectedComponentTypes && filter.selectedComponentTypes.length > 0) || (filter.selectedResourceSubTypes && filter.selectedResourceSubTypes.length > 0)) { + let filteredTypes = []; + angular.forEach(components, (component:Component):void => { + // Filter by component type + let typeLower:string = component.componentType.toLowerCase(); + let typeFirstCapital:string = typeLower.charAt(0).toUpperCase() + typeLower.slice(1); + if (filter.selectedComponentTypes.indexOf(typeFirstCapital) !== -1) { + filteredTypes.push(component); + } + + // Filter by resource sub type, only in case the resource checkbox was not selected (because in this case we already added all the components in above section). + if (component.isResource() && filter.selectedComponentTypes.indexOf("Resource") === -1 && filter.selectedResourceSubTypes.length > 0) { + //filteredComponents.pop(); // Remove the last inserted component. + let resource:Resource = component; + if (filter.selectedResourceSubTypes.indexOf(resource.getComponentSubType()) !== -1) { + filteredTypes.push(component); + } + } + }); + filteredComponents = filteredTypes; + } + + // filter by categories & subcategories & groupings + // -------------------------------------------------------------------------- + if (filter.selectedCategoriesModel && filter.selectedCategoriesModel.length > 0) { + let filteredCategories = []; + angular.forEach(filteredComponents, (component:Component):void => { + let componentCategory = component.categoryNormalizedName + + ((component.subCategoryNormalizedName) ? '.' + component.subCategoryNormalizedName : ''); + if (component.componentType === ComponentType.RESOURCE) { + componentCategory = 'resourceNewCategory.' + componentCategory; + } else if (component.componentType === ComponentType.SERVICE) { + componentCategory = 'serviceNewCategory.' + componentCategory; + } + if (filter.selectedCategoriesModel.indexOf(componentCategory) !== -1) { + filteredCategories.push(component); + } + }); + filteredComponents = filteredCategories; + } + + // filter by statuses + // -------------------------------------------------------------------------- + if (filter.selectedStatuses && filter.selectedStatuses.length > 0) { + + let filteredStatuses = []; + angular.forEach(filteredComponents, (component:Component):void => { + if (filter.selectedStatuses.indexOf(component.lifecycleState) > -1) { + filteredStatuses.push(component); + } + //if status DISTRIBUTED && CERTIFIED are selected the component will added in CERTIFIED status , not need to add twice + if (filter.selectedStatuses.indexOf('DISTRIBUTED') > -1 && !(filter.selectedStatuses.indexOf('CERTIFIED') > -1)) { + if (component.distributionStatus && component.distributionStatus.indexOf('DISTRIBUTED') > -1 && component.lifecycleState.indexOf('CERTIFIED') > -1) { + filteredStatuses.push(component); + } + } + }); + filteredComponents = filteredStatuses; + } + + // filter by statuses and distributed + // -------------------------------------------------------------------------- + if (filter.distributed != undefined && filter.distributed.length > 0) { + let filterDistributed:Array = filter.distributed; + let filteredDistributed = []; + angular.forEach(filteredComponents, (entity) => { + filterDistributed.forEach((distribute) => { + let distributeItem = distribute.split(','); + distributeItem.forEach((item) => { + if (item !== undefined && entity.distributionStatus === item) { + filteredDistributed.push(entity); + } + }) + }); + }); + filteredComponents = filteredDistributed; + } + + // filter by search + // -------------------------------------------------------------------------- + if (filter.search != undefined) { + Object.keys(filter.search).forEach((searchKey) => { + let searchVal = filter.search[searchKey]; + if (searchVal) { + searchVal = searchVal.toLowerCase(); + filteredComponents = filteredComponents.filter((component:Component) => + component[searchKey].toLowerCase().indexOf(searchVal) !== -1); + } + }); + } + + return filteredComponents; + } + + public transform(components:Array, filter:IEntityFilterObject) { + return EntityFilterPipe.transform(components, filter); + } +} diff --git a/catalog-ui/src/app/ng2/pipes/global-pipes.module.ts b/catalog-ui/src/app/ng2/pipes/global-pipes.module.ts index c44d71b30d..66f9518a47 100644 --- a/catalog-ui/src/app/ng2/pipes/global-pipes.module.ts +++ b/catalog-ui/src/app/ng2/pipes/global-pipes.module.ts @@ -26,7 +26,10 @@ import {GroupByPipe} from "./groupBy.pipe"; import {ResourceNamePipe} from "./resource-name.pipe"; import {NgModule} from "@angular/core"; import {SafeUrlSanitizerPipe} from "./safeUrlSanitizer.pipe"; -import {OrderByPipe} from "./orderBy.pipe"; +import {EntityFilterPipe} from "./entity-filter.pipe"; +import {KeyValuePipe} from "./key-value.pipe"; +import {PropertiesOrderByPipe} from "./properties-order-by.pipe"; +import {OrderByPipe} from "./order-by.pipe"; @NgModule({ declarations: [ @@ -36,6 +39,9 @@ import {OrderByPipe} from "./orderBy.pipe"; SafeUrlSanitizerPipe, SearchFilterPipe, ResourceNamePipe, + EntityFilterPipe, + KeyValuePipe, + PropertiesOrderByPipe, OrderByPipe ], exports: [ @@ -45,7 +51,20 @@ import {OrderByPipe} from "./orderBy.pipe"; SafeUrlSanitizerPipe, SearchFilterPipe, ResourceNamePipe, - OrderByPipe + EntityFilterPipe, + PropertiesOrderByPipe, + OrderByPipe, + KeyValuePipe + ], + providers: [ + ContentAfterLastDotPipe, + GroupByPipe, + KeysPipe, + SafeUrlSanitizerPipe, + SearchFilterPipe, + ResourceNamePipe, + EntityFilterPipe, + KeyValuePipe ] }) diff --git a/catalog-ui/src/app/ng2/pipes/groupBy.pipe.ts b/catalog-ui/src/app/ng2/pipes/groupBy.pipe.ts index 90dce23352..19811f2f08 100644 --- a/catalog-ui/src/app/ng2/pipes/groupBy.pipe.ts +++ b/catalog-ui/src/app/ng2/pipes/groupBy.pipe.ts @@ -26,6 +26,9 @@ import {Pipe, PipeTransform} from '@angular/core'; @Pipe({name: 'groupBy'}) export class GroupByPipe implements PipeTransform { transform(value: Array, field: string): Array { + if(!value) { + return null; + } const groupedObj = value.reduce((prev, cur)=> { if(!prev[cur[field]]) { prev[cur[field]] = [cur]; diff --git a/catalog-ui/src/app/ng2/pipes/key-value.pipe.ts b/catalog-ui/src/app/ng2/pipes/key-value.pipe.ts new file mode 100644 index 0000000000..4adb0b12f7 --- /dev/null +++ b/catalog-ui/src/app/ng2/pipes/key-value.pipe.ts @@ -0,0 +1,41 @@ +/** + * Created by ob0695 on 7/3/2018. + */ +/*- + * ============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 rc2122 on 5/17/2017. + */ +import {Pipe, PipeTransform} from '@angular/core'; + +@Pipe({name: 'keyValue'}) +export class KeyValuePipe implements PipeTransform { + transform(value, field: string): Array { + if(!value) { + return null; + } + let keyValueObject = []; + for (let key in value) { + keyValueObject.push({key:key, value: value[key]}); + } + return keyValueObject; + } +} diff --git a/catalog-ui/src/app/ng2/pipes/keys.pipe.ts b/catalog-ui/src/app/ng2/pipes/keys.pipe.ts index 349e9334f7..f8663aca2e 100644 --- a/catalog-ui/src/app/ng2/pipes/keys.pipe.ts +++ b/catalog-ui/src/app/ng2/pipes/keys.pipe.ts @@ -23,6 +23,9 @@ import { Pipe, PipeTransform } from '@angular/core'; @Pipe({name: 'keys'}) export class KeysPipe implements PipeTransform { transform(value, args:string[]) : any { + if(!value) { + return null; + } let keys = []; for (let key in value) { keys.push(key); diff --git a/catalog-ui/src/app/ng2/pipes/order-by.pipe.ts b/catalog-ui/src/app/ng2/pipes/order-by.pipe.ts new file mode 100644 index 0000000000..6dc5d47863 --- /dev/null +++ b/catalog-ui/src/app/ng2/pipes/order-by.pipe.ts @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 Huawei 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========================================================= + */ + +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({name: 'orderBy'}) +export class OrderByPipe implements PipeTransform { + transform(records: Array, args?: any): any { + if (!records || !args.path) { return records; } + let len = args.path.length; + return records.sort((itemIdx1, itemIdx2) => { + var i = 0; + while (i < len) { itemIdx1 = itemIdx1[args.path[i]]; itemIdx2 = itemIdx2[args.path[i]]; i++; } + // Order * (-1): We change our order + return itemIdx1 + "" > itemIdx2 + "" ? args.direction : args.direction * (- 1); + }) + }; +} diff --git a/catalog-ui/src/app/ng2/pipes/orderBy.pipe.ts b/catalog-ui/src/app/ng2/pipes/orderBy.pipe.ts deleted file mode 100644 index 4edbd60f60..0000000000 --- a/catalog-ui/src/app/ng2/pipes/orderBy.pipe.ts +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 Huawei 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========================================================= - */ - -import { Pipe, PipeTransform } from '@angular/core'; - -@Pipe({ name: 'orderBy' }) -export class OrderByPipe implements PipeTransform { - transform(records: Array, args?: any): any { - if (!records || !args.path) return records; - let len = args.path.length; - return records.sort((itemIdx1, itemIdx2) => { - var i = 0; - while (i < len) { itemIdx1 = itemIdx1[args.path[i]]; itemIdx2 = itemIdx2[args.path[i]]; i++; } - // Order * (-1): We change our order - return itemIdx1 + "" > itemIdx2 + "" ? args.direction : args.direction * (- 1); - }) - }; -} diff --git a/catalog-ui/src/app/ng2/pipes/properties-order-by.pipe.ts b/catalog-ui/src/app/ng2/pipes/properties-order-by.pipe.ts new file mode 100644 index 0000000000..98debd28d9 --- /dev/null +++ b/catalog-ui/src/app/ng2/pipes/properties-order-by.pipe.ts @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 Huawei 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========================================================= + */ + +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ name: 'propertiesOrderBy' }) +export class PropertiesOrderByPipe implements PipeTransform { + transform(records: Array, args?: any): any { + if (!records || !args.path) return records; + let len = args.path.length; + return records.sort((itemIdx1, itemIdx2) => { + var i = 0; + while (i < len) { itemIdx1 = itemIdx1[args.path[i]]; itemIdx2 = itemIdx2[args.path[i]]; i++; } + // Order * (-1): We change our order + return itemIdx1 + "" > itemIdx2 + "" ? args.direction : args.direction * (- 1); + }) + }; +} diff --git a/catalog-ui/src/app/ng2/pipes/resource-name.pipe.ts b/catalog-ui/src/app/ng2/pipes/resource-name.pipe.ts index fdf9526375..0fdbbcaade 100644 --- a/catalog-ui/src/app/ng2/pipes/resource-name.pipe.ts +++ b/catalog-ui/src/app/ng2/pipes/resource-name.pipe.ts @@ -20,15 +20,20 @@ import { Pipe, PipeTransform } from '@angular/core'; +import * as _ from 'lodash'; @Pipe({name: 'resourceName'}) export class ResourceNamePipe implements PipeTransform { + + public static getDisplayName (value:string): string { + const newName:string = + _.last(value.split(/tosca\.nodes\..*network\..*relationships\..*org\.openecomp\..*resource\.nfv\..*nodes\.module\..*cp\..*vl\./)); + return (newName) ? newName : value; + } + transform(value) : any { if (value) { - //newName = _.last(newName.split('.')); - const newName:string = - _.last(value.split(/tosca\.nodes\..*network\..*relationships\..*org\.openecomp\..*resource\.nfv\..*nodes\.module\..*cp\..*vl\./)); - return (newName) ? newName : value; + return ResourceNamePipe.getDisplayName(value); } } } diff --git a/catalog-ui/src/app/ng2/services/activity-log.service.ts b/catalog-ui/src/app/ng2/services/activity-log.service.ts new file mode 100644 index 0000000000..deabbee0bd --- /dev/null +++ b/catalog-ui/src/app/ng2/services/activity-log.service.ts @@ -0,0 +1,48 @@ +/*- + * ============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========================================================= + */ + +import { HttpClient } from '@angular/common/http'; +import { Inject, Injectable} from '@angular/core'; +import { Observable } from 'rxjs/Observable'; +import { Activity } from '../../models/activity'; +import { ServerTypeUrl } from '../../utils/constants'; +import { ISdcConfig, SdcConfigToken } from '../config/sdc-config.config'; +import { HttpHelperService } from './http-hepler.service'; + +@Injectable() +export class ActivityLogService { + url: string; + + constructor(private httpClient: HttpClient, @Inject(SdcConfigToken) private sdcConfig:ISdcConfig) { + this.url = this.sdcConfig.api.root + this.sdcConfig.api.GET_activity_log; + } + + public getActivityLog(componentType: string, uid: string): Observable { + + // Compose URL: audit-records/services_or_resources/uid + const url = HttpHelperService.replaceUrlParams(this.url, { + type: ServerTypeUrl.toServerTypeUrl(componentType), + id: uid + }); + + return this.httpClient.get(url); + } + +} diff --git a/catalog-ui/src/app/ng2/services/archive.service.ts b/catalog-ui/src/app/ng2/services/archive.service.ts deleted file mode 100644 index 83f1c502c2..0000000000 --- a/catalog-ui/src/app/ng2/services/archive.service.ts +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * ============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========================================================= - */ - -import { Injectable, Inject } from "@angular/core"; -import { Observable } from "rxjs/Observable"; -import { HttpService } from "./http.service"; -import { SdcConfigToken, ISdcConfig } from "../config/sdc-config.config"; -import { Component } from "../../models"; -import { ComponentFactory } from 'app/utils/component-factory'; - - -@Injectable() -export class ArchiveService { - protected baseUrl; - - constructor(private http: HttpService, @Inject(SdcConfigToken) sdcConfig:ISdcConfig, private componentFactory:ComponentFactory/*, @Inject(ComponentFactory) componentFactory */) { - this.baseUrl = sdcConfig.api.root ; - } - - public getArchiveCatalog() { - let archiveCatalogItems:Component[] = []; - let archiveCatalogResourceItems:Component[] = []; - let archiveCatalogServiceItems:Component[] = []; - - return this.http.get(this.baseUrl + '/v1/catalog/archive/', {}).map(res => { - let archiveCatalogObject = res.json(); - if (archiveCatalogObject.resources) archiveCatalogResourceItems = this.getResourceItems(archiveCatalogObject.resources); - if (archiveCatalogObject.services) archiveCatalogServiceItems = this.getServiceItems(archiveCatalogObject.services); - archiveCatalogItems = [].concat(archiveCatalogResourceItems, archiveCatalogServiceItems); - - return archiveCatalogItems; - }); - } - - - private getResourceItems(resources){ - let resourceItems = resources.map((resource)=>{ - return this.componentFactory.createResource(resource) - }) - return resourceItems; - } - - private getServiceItems(services){ - let serviceItems = services.map((service)=>{ - return this.componentFactory.createService(service) - }) - return serviceItems; - } - -} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/services/authentication.service.ts b/catalog-ui/src/app/ng2/services/authentication.service.ts index 1c6502dd0d..52ca643833 100644 --- a/catalog-ui/src/app/ng2/services/authentication.service.ts +++ b/catalog-ui/src/app/ng2/services/authentication.service.ts @@ -20,38 +20,44 @@ import {Injectable, Inject} from '@angular/core'; import {IAppConfigurtaion, ICookie} from "../../models/app-config"; -import {Response, Headers, RequestOptions, Http} from '@angular/http'; import {Cookie2Service} from "./cookie.service"; import { Observable } from 'rxjs/Observable'; import {SdcConfigToken, ISdcConfig} from "../config/sdc-config.config"; +import { IUserProperties } from "app/models"; +import { CacheService } from "app/ng2/services/cache.service"; +import { HttpClient, HttpHeaders } from '@angular/common/http'; @Injectable() export class AuthenticationService { - constructor(private cookieService:Cookie2Service, private http: Http, @Inject(SdcConfigToken) private sdcConfig:ISdcConfig) { + private _loggedinUser:IUserProperties; + + constructor(private cookieService:Cookie2Service, private http: HttpClient, @Inject(SdcConfigToken) private sdcConfig:ISdcConfig, private cacheService: CacheService) { this.cookieService = cookieService; - this.http = http; } - private getAuthHeaders():any { + private getAuthHeaders():HttpHeaders { let cookie:ICookie = this.sdcConfig.cookie; - let authHeaders:any = {}; - authHeaders[cookie.userFirstName] = this.cookieService.getFirstName(); - authHeaders[cookie.userLastName] = this.cookieService.getLastName(); - authHeaders[cookie.userEmail] = this.cookieService.getEmail(); - authHeaders[cookie.userIdSuffix] = this.cookieService.getUserId(); + let authHeaders: HttpHeaders = new HttpHeaders(); + authHeaders = authHeaders.set(cookie.userFirstName, this.cookieService.getFirstName()) + .set(cookie.userLastName, this.cookieService.getLastName()) + .set(cookie.userEmail, this.cookieService.getEmail()) + .set(cookie.userIdSuffix, this.cookieService.getUserId()) return authHeaders; } - public authenticate(): Observable { - let options = new RequestOptions({ - headers: new Headers(this.getAuthHeaders()) - }); - + public authenticate(): Observable { let authUrl = this.sdcConfig.api.root + this.sdcConfig.api.GET_user_authorize; - return this.http - .get(authUrl, options) - .map((res: Response) => res.json()); + return this.http.get(authUrl, {headers: this.getAuthHeaders()}); + } + + public getLoggedinUser():IUserProperties { + return this._loggedinUser; } + public setLoggedinUser(loggedinUser:IUserProperties) { + this._loggedinUser = loggedinUser; + this.cacheService.set('user', loggedinUser); + }; + } diff --git a/catalog-ui/src/app/ng2/services/cache.service.ts b/catalog-ui/src/app/ng2/services/cache.service.ts new file mode 100644 index 0000000000..e876ec1098 --- /dev/null +++ b/catalog-ui/src/app/ng2/services/cache.service.ts @@ -0,0 +1,49 @@ +/*- + * ============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========================================================= + */ + +import {Injectable} from "@angular/core"; +import {Dictionary} from "app/utils"; + +@Injectable() +export class CacheService { + private storage:Dictionary; + + constructor() { + this.storage = new Dictionary(); + }; + + public get(key:string): any { + return this.storage.getValue(key); + } + + public set(key:string, value:any): void { + this.storage.setValue(key, value); + } + + public remove(key:string): void { + if (this.storage.containsKey(key)) { + this.storage.remove(key); + } + } + + public contains(key:string): boolean { + return this.storage.containsKey(key); + } +} diff --git a/catalog-ui/src/app/ng2/services/catalog.service.ts b/catalog-ui/src/app/ng2/services/catalog.service.ts new file mode 100644 index 0000000000..bbdfa1b420 --- /dev/null +++ b/catalog-ui/src/app/ng2/services/catalog.service.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========================================================= + */ + +import { Injectable, Inject } from "@angular/core"; +import { Observable } from "rxjs/Observable"; +import { SdcConfigToken, ISdcConfig } from "../config/sdc-config.config"; +import { Component, IApi, IComponentsArray } from "app/models"; +import { ComponentFactory } from 'app/utils/component-factory'; +import {ResourceType} from "../../utils/constants"; +import {SharingService} from "./sharing.service"; +import { HttpClient, HttpParams } from "@angular/common/http"; + +@Injectable() +export class CatalogService { + protected api:IApi; + protected baseUrl:string; + protected baseMicroServiceUrl:string; + + constructor(private http: HttpClient, + @Inject(SdcConfigToken) sdcConfig:ISdcConfig, + private componentFactory:ComponentFactory, + private sharingService:SharingService) { + this.api = sdcConfig.api; + this.baseUrl = sdcConfig.api.root ; + this.baseMicroServiceUrl = sdcConfig.api.uicache_root; + } + + public getCatalog(): Observable> { + let searchParams = new HttpParams(); + searchParams = searchParams.append('excludeTypes', ResourceType.VFCMT).append('excludeTypes', ResourceType.CONFIGURATION); + return this.http.get(this.baseMicroServiceUrl + this.api.GET_uicache_catalog, {params: searchParams}) + .map(res => this.processComponentsResponse(res, true)); + } + + public getArchiveCatalog() { + return this.http.get(this.baseUrl + '/v1/catalog/archive/', {}) + .map(res => this.processComponentsResponse(res)); + } + + private processComponentsResponse(componentsArr: IComponentsArray, addSharing:boolean = false) { + const componentsList: Component[] = []; + if (componentsArr.resources) { + componentsList.push(...this.getResourceItems(componentsArr.resources)); + } + if (componentsArr.services) { + componentsList.push(...this.getServiceItems(componentsArr.services)); + } + if (addSharing) { + componentsList.forEach((item) => this.sharingService.addUuidValue(item.uniqueId, item.uuid)); + } + return componentsList; + } + + private getResourceItems(resources){ + let resourceItems = resources.map((resource)=>{ + return this.componentFactory.createResource(resource) + }) + return resourceItems; + } + + private getServiceItems(services){ + let serviceItems = services.map((service)=>{ + return this.componentFactory.createService(service) + }) + return serviceItems; + } + +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/services/component-instance-services/component-instance.service.ts b/catalog-ui/src/app/ng2/services/component-instance-services/component-instance.service.ts index 15750020dc..cc382a3df0 100644 --- a/catalog-ui/src/app/ng2/services/component-instance-services/component-instance.service.ts +++ b/catalog-ui/src/app/ng2/services/component-instance-services/component-instance.service.ts @@ -19,62 +19,102 @@ */ import {Injectable, Inject} from '@angular/core'; -import {Response, RequestOptions, Headers} from '@angular/http'; import { Observable } from 'rxjs/Observable'; import {PropertyFEModel, PropertyBEModel} from "app/models"; -import {CommonUtils} from "app/utils"; -import {Component, ComponentInstance, Capability, PropertyModel} from "app/models"; -import { HttpService } from '../http.service'; +import {CommonUtils, ComponentType, ServerTypeUrl, ComponentInstanceFactory} from "app/utils"; +import {Component, ComponentInstance, Capability, PropertyModel, ArtifactGroupModel, ArtifactModel, AttributeModel, IFileDownload} from "app/models"; import {SdcConfigToken, ISdcConfig} from "../../config/sdc-config.config"; +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { InputBEModel } from '../../../models/properties-inputs/input-be-model'; +import { HttpHelperService } from '../http-hepler.service'; @Injectable() export class ComponentInstanceServiceNg2 { protected baseUrl; - constructor(private http: HttpService, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) { + constructor(private http: HttpClient, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) { this.baseUrl = sdcConfig.api.root + sdcConfig.api.component_api_root; } + private getServerTypeUrl = (componentType:string):string => { + switch (componentType) { + case ComponentType.SERVICE: + return ServerTypeUrl.SERVICES; + default: + return ServerTypeUrl.RESOURCES; + } + } getComponentInstanceProperties(component: Component, componentInstanceId: string): Observable> { - - return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/componentInstances/' + componentInstanceId + '/properties') - .map((res: Response) => { - return CommonUtils.initBeProperties(res.json()); + return this.http.get>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/componentInstances/' + componentInstanceId + '/properties') + .map(res => { + return CommonUtils.initBeProperties(res); }) } getComponentInstanceInputs(component: Component, componentInstance: ComponentInstance): Observable> { - return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/componentInstances/' + componentInstance.uniqueId + '/' + componentInstance.componentUid + '/inputs') - .map((res: Response) => { - return CommonUtils.initInputs(res.json()); + return this.http.get>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/componentInstances/' + componentInstance.uniqueId + '/' + componentInstance.componentUid + '/inputs') + .map(res => { + return CommonUtils.initInputs(res); }) } - updateInstanceProperties(component: Component, componentInstanceId: string, properties: PropertyBEModel[]) { + getComponentInstanceArtifactsByGroupType = (componentType:string, componentId:string, componentInstanceId:string, artifactGroupType:string):Observable => { + + return this.http.get(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + "/resourceInstances/" + componentInstanceId + "/artifactsByType/" + artifactGroupType) + .map(res => { + return new ArtifactGroupModel(res); + }); + }; + + getArtifactByGroupType = (componentType:string, componentId:string, artifactGroupType:string):Observable => { + + return this.http.get(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + "/artifactsByType/" + artifactGroupType) + .map(response => new ArtifactGroupModel(response)); + }; + + changeResourceInstanceVersion = (componentType:string, componentId:string, componentInstanceId:string, componentUid:string):Observable => { + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance/' + componentInstanceId + '/changeVersion', {'componentUid': componentUid}) + .map((res) => { + return ComponentInstanceFactory.createComponentInstance(res); + }) + }; - return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstance/' + componentInstanceId + '/properties', properties) - .map((res: Response) => { - return res.json().map((resProperty) => new PropertyBEModel(resProperty)); + updateComponentInstance = (componentType:string, componentId:string, componentInstance:ComponentInstance):Observable => { + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance/' + componentInstance.uniqueId, componentInstance.toJSON()) + .map((response) => { + return ComponentInstanceFactory.createComponentInstance(response); + }); + }; + + updateInstanceProperties(componentType:string, componentId:string, componentInstanceId: string, properties: PropertyBEModel[]) { + + return this.http.post>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance/' + componentInstanceId + '/properties', properties) + .map((res) => { + return res.map((resProperty) => { + let newProp = new PropertyModel(resProperty); + newProp.resourceInstanceUniqueId = componentInstanceId + return newProp; + }); }); } - getInstanceCapabilityProperties(component: Component, componentInstanceId: string, capability: Capability): Observable> { + getInstanceCapabilityProperties(componentType: string, componentId: string, componentInstanceId: string, capability: Capability): Observable> { - return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/componentInstances/' + componentInstanceId + '/capability/' + capability.type + + return this.http.get>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/componentInstances/' + componentInstanceId + '/capability/' + capability.type + '/capabilityName/' + capability.name + '/ownerId/' + capability.ownerId + '/properties') - .map((res: Response) => { - capability.properties = res.json().map((capProp) => new PropertyModel(capProp)); // update capability properties + .map((res) => { + capability.properties = res.map((capProp) => new PropertyModel(capProp)); // update capability properties return capability.properties; }) } updateInstanceCapabilityProperties(component: Component, componentInstanceId: string, capability: Capability, properties: PropertyBEModel[]): Observable> { - return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/componentInstances/' + componentInstanceId + '/capability/' + capability.type + + return this.http.put>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/componentInstances/' + componentInstanceId + '/capability/' + capability.type + '/capabilityName/' + capability.name + '/ownerId/' + capability.ownerId + '/properties', properties) - .map((res: Response) => { - const savedProperties: PropertyModel[] = res.json().map((resProperty) => new PropertyModel(resProperty)); + .map((res) => { + const savedProperties: PropertyModel[] = res.map((resProperty) => new PropertyModel(resProperty)); savedProperties.forEach((savedProperty) => { const propIdx = capability.properties.findIndex((p) => p.uniqueId === savedProperty.uniqueId); if (propIdx !== -1) { @@ -87,37 +127,87 @@ export class ComponentInstanceServiceNg2 { updateInstanceInputs(component: Component, componentInstanceId: string, inputs: PropertyBEModel[]): Observable { - return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstance/' + componentInstanceId + '/inputs', inputs) - .map((res: Response) => { - return res.json().map((resInput) => new PropertyBEModel(resInput)); + return this.http.post>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstance/' + componentInstanceId + '/inputs', inputs) + .map((res) => { + return res.map((resInput) => new PropertyBEModel(resInput)); }); } getComponentGroupInstanceProperties(component: Component, groupInstanceId: string): Observable> { - return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/groups/' + groupInstanceId + '/properties') - .map((res: Response) => { - return CommonUtils.initBeProperties(res.json()); + return this.http.get>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/groups/' + groupInstanceId + '/properties') + .map((res) => { + return CommonUtils.initBeProperties(res); + }); + } + + updateComponentGroupInstanceProperties(componentType:string, componentId:string, groupInstanceId: string, properties: PropertyBEModel[]): Observable> { + return this.http.put>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/groups/' + groupInstanceId + '/properties', properties) + .map((res) => { + return res.map((resProperty) => new PropertyBEModel(resProperty)); }); } - updateComponentGroupInstanceProperties(component: Component, groupInstanceId: string, properties: PropertyBEModel[]): Observable> { - return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/groups/' + groupInstanceId + '/properties', properties) - .map((res: Response) => { - return res.json().map((resProperty) => new PropertyBEModel(resProperty)); + getComponentPolicyInstanceProperties(componentType:string, componentId:string, policyInstanceId: string): Observable> { + return this.http.get>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/policies/' + policyInstanceId + '/properties') + .map((res) => { + return CommonUtils.initBeProperties(res); }); } - getComponentPolicyInstanceProperties(component: Component, policyInstanceId: string): Observable> { - return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/policies/' + policyInstanceId + '/properties') - .map((res: Response) => { - return CommonUtils.initBeProperties(res.json()); + updateComponentPolicyInstanceProperties(componentType:string, componentId:string, policyInstanceId: string, properties: PropertyBEModel[]): Observable> { + return this.http.put>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/policies/' + policyInstanceId + '/properties', properties) + .map((res) => { + return res.map((resProperty) => new PropertyBEModel(resProperty)); }); } - updateComponentPolicyInstanceProperties(component: Component, policyInstanceId: string, properties: PropertyBEModel[]): Observable> { - return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/policies/' + policyInstanceId + '/properties', properties) - .map((res: Response) => { - return res.json().map((resProperty) => new PropertyBEModel(resProperty)); + addInstanceArtifact = (componentType:string, componentId:string, instanceId:string, artifact:ArtifactModel):Observable => { + // let deferred = this.$q.defer(); + let headerObj = new HttpHeaders(); + if (artifact.payloadData) { + headerObj = headerObj.set('Content-MD5', HttpHelperService.getHeaderMd5(artifact)); + } + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance/' + instanceId + '/artifacts', JSON.stringify(artifact), {headers: headerObj}) + .map((res) => { + return new ArtifactModel(res); + }); + }; + + updateInstanceArtifact = (componentType:string, componentId:string, instanceId:string, artifact:ArtifactModel):Observable => { + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance/' + instanceId + '/artifacts/' + artifact.uniqueId, artifact).map((res) => { + return new ArtifactModel(res); + });; + }; + + deleteInstanceArtifact = (componentId:string, componentType:string, instanceId:string, artifactId:string, artifactLabel:string):Observable => { + return this.http.delete(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + "/resourceInstance/" + instanceId + '/artifacts/' + artifactId + '?operation=' + artifactLabel) + .map((res) => { + return new ArtifactModel(res); }); } + + downloadInstanceArtifact = (componentType:string, componentId:string, instanceId:string, artifactId:string):Observable => { + return this.http.get(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + "/resourceInstances/" + instanceId + "/artifacts/" + artifactId); + }; + + uploadInstanceEnvFile = (componentType:string, componentId:string, instanceId:string, artifact:ArtifactModel):Observable => { + let headerObj = new HttpHeaders(); + if (artifact.payloadData) { + headerObj = headerObj.set('Content-MD5', HttpHelperService.getHeaderMd5(artifact)); + } + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance/' + instanceId + '/artifacts/' + artifact.uniqueId, JSON.stringify(artifact), {headers: headerObj}); + }; + + + updateInstanceAttribute = (componentType:string, componentId:string, attribute:AttributeModel):Observable => { + let instanceId = attribute.resourceInstanceUniqueId; + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + "/resourceInstance/" + instanceId + "/attribute", attribute) + .map((response) => { + let newAttribute = new AttributeModel(response); + newAttribute.readonly = true; + newAttribute.resourceInstanceUniqueId = instanceId; + return newAttribute; + }); + }; + } diff --git a/catalog-ui/src/app/ng2/services/component-services/component-mode.service.ts b/catalog-ui/src/app/ng2/services/component-services/component-mode.service.ts index b0cc1b8f1a..9952b03c7c 100644 --- a/catalog-ui/src/app/ng2/services/component-services/component-mode.service.ts +++ b/catalog-ui/src/app/ng2/services/component-services/component-mode.service.ts @@ -24,7 +24,7 @@ import { Injectable } from '@angular/core'; import {WorkspaceMode, ComponentState, Role} from "../../../utils/constants"; import { Component as ComponentData } from "app/models"; -import { CacheService } from "app/services/cache-service" +import { CacheService } from "app/services-ng2"; @Injectable() diff --git a/catalog-ui/src/app/ng2/services/component-services/component.service.factory.ts b/catalog-ui/src/app/ng2/services/component-services/component.service.factory.ts index 6e9d0e8031..15e5a7960a 100644 --- a/catalog-ui/src/app/ng2/services/component-services/component.service.factory.ts +++ b/catalog-ui/src/app/ng2/services/component-services/component.service.factory.ts @@ -20,15 +20,18 @@ import {Injectable} from "@angular/core"; -import {Component} from "../../../models/components/component"; +import {Component} from "app/models"; import {ComponentServiceNg2} from "./component.service"; import {ServiceServiceNg2} from "./service.service"; +import {CacheService} from "app/services-ng2"; @Injectable() export class ComponentServiceFactoryNg2 { + componentService: ComponentServiceNg2; serviceService: ServiceServiceNg2; - constructor(componentService: ComponentServiceNg2, serviceService: ServiceServiceNg2) { + + constructor(componentService: ComponentServiceNg2, serviceService: ServiceServiceNg2, private cacheService:CacheService) { this.serviceService = serviceService; this.componentService = componentService; } diff --git a/catalog-ui/src/app/ng2/services/component-services/component.service.ts b/catalog-ui/src/app/ng2/services/component-services/component.service.ts index 445e1231f9..760bfc591b 100644 --- a/catalog-ui/src/app/ng2/services/component-services/component.service.ts +++ b/catalog-ui/src/app/ng2/services/component-services/component.service.ts @@ -23,51 +23,52 @@ import {Injectable, Inject} from '@angular/core'; import {Observable} from 'rxjs/Observable'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/toPromise'; -import {Response, URLSearchParams, Headers} from '@angular/http'; -import { Component, ComponentInstance, InputBEModel, InstancePropertiesAPIMap, FilterPropertiesAssignmentData, - PropertyBEModel, InterfaceModel, OperationModel, BEOperationModel, Capability, Requirement, PolicyInstance} from "app/models"; -import {COMPONENT_FIELDS, CommonUtils, SERVICE_FIELDS} from "app/utils"; -import {downgradeInjectable} from '@angular/upgrade/static'; +import { Component, InputBEModel, InstancePropertiesAPIMap, FilterPropertiesAssignmentData, OperationModel, CreateOperationResponse, ArtifactModel} from "app/models"; +import {COMPONENT_FIELDS} from "app/utils"; import {ComponentGenericResponse} from "../responses/component-generic-response"; import {InstanceBePropertiesMap} from "../../../models/properties-inputs/property-fe-map"; import {API_QUERY_PARAMS} from "app/utils"; -import { ComponentType, ServerTypeUrl } from "../../../utils/constants"; -import { HttpService } from '../http.service'; +import {ComponentType, ServerTypeUrl, SERVICE_FIELDS} from "../../../utils/constants"; import {SdcConfigToken, ISdcConfig} from "../../config/sdc-config.config"; -import {ConstraintObject} from 'app/ng2/components/logic/service-dependencies/service-dependencies.component'; import {IDependenciesServerResponse} from "../responses/dependencies-server-response"; import {AutomatedUpgradeGenericResponse} from "../responses/automated-upgrade-response"; import {IAutomatedUpgradeRequestObj} from "../../pages/automated-upgrade/automated-upgrade.service"; - -declare var angular:angular.IAngularStatic; - +import {ComponentInstance} from "../../../models/componentsInstances/componentInstance"; +import {CommonUtils} from "../../../utils/common-utils"; +import {RelationshipModel} from "../../../models/graph/relationship"; +import { HttpClient, HttpParams, HttpHeaders } from "@angular/common/http"; +import { BEOperationModel, InterfaceModel } from "../../../models/operation"; +import { PropertyBEModel } from "../../../models/properties-inputs/property-be-model"; +import { PolicyInstance } from "../../../models/graph/zones/policy-instance"; +import { ConstraintObject } from "../../components/logic/service-dependencies/service-dependencies.component"; +import { Requirement } from "../../../models/requirement"; +import { Capability } from "../../../models/capability"; + +/* +PLEASE DO NOT USE THIS SERVICE IN ANGULAR2! Use the topology-template.service instead + */ @Injectable() export class ComponentServiceNg2 { protected baseUrl; - constructor(protected http:HttpService, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) { + constructor(protected http: HttpClient, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) { this.baseUrl = sdcConfig.api.root + sdcConfig.api.component_api_root; } - protected getComponentDataByFieldsName(componentType:string, componentId: string, fields:Array):Observable { + protected getComponentDataByFieldsName(componentType:string, componentId:string, fields:Array):Observable { - let params:URLSearchParams = new URLSearchParams(); + let params: HttpParams = new HttpParams(); _.forEach(fields, (field:string):void => { - params.append(API_QUERY_PARAMS.INCLUDE, field); + params = params.append(API_QUERY_PARAMS.INCLUDE, field); }); - return this.http.get(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/filteredDataByParams', {search: params}) - .map((res:Response) => { - return this.analyzeComponentDataResponse(res); + return this.http.get(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/filteredDataByParams', {params: params}) + .map((res) => { + return new ComponentGenericResponse().deserialize(res); }); } - - protected analyzeComponentDataResponse(res: Response):ComponentGenericResponse { - return new ComponentGenericResponse().deserialize(res.json()); - } - - private getServerTypeUrl = (componentType:string):string => { + protected getServerTypeUrl = (componentType:string):string => { switch (componentType) { case ComponentType.SERVICE: return ServerTypeUrl.SERVICES; @@ -76,15 +77,23 @@ export class ComponentServiceNg2 { } } - getComponentMetadata(component:Component):Observable { - return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_METADATA]); + getFullComponent(uniqueId:string):Observable { + return this.http.get(this.baseUrl + uniqueId) + .map((res) => { + return new ComponentGenericResponse().deserialize(res); + }); } + getComponentMetadata(uniqueId:string, type:string):Observable { + return this.getComponentDataByFieldsName(type, uniqueId, [COMPONENT_FIELDS.COMPONENT_METADATA]); + } + + getComponentInstanceAttributesAndProperties(component:Component):Observable { return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES, COMPONENT_FIELDS.COMPONENT_INSTANCES_ATTRIBUTES]); } - getComponentInstanceProperties(component:Component):Observable { + getComponentInstanceProperties(component:Component): Observable { return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES]); } @@ -132,17 +141,15 @@ export class ComponentServiceNg2 { return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_PROPERTIES]); } - getInterfaces(component:Component):Observable { + getInterfaceOperations(component:Component):Observable { return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INTERFACE_OPERATIONS]); } getInterfaceOperation(component:Component, operation:OperationModel):Observable { - return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaces/' + operation.interfaceId + '/operations/' + operation.uniqueId) - .map((res:Response) => { - return res.json(); - }); + return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations/' + operation.uniqueId); } + // tslint:disable-next-line:member-ordering createInterfaceOperation(component:Component, operation:OperationModel):Observable { const operationList = { 'interfaces': { @@ -154,9 +161,9 @@ export class ComponentServiceNg2 { } } }; - return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations', operationList) - .map((res:Response) => { - const interf:InterfaceModel = _.find(res.json().interfaces, interf => interf.type === operation.interfaceType); + return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations', operationList) + .map((res:any) => { + const interf:InterfaceModel = _.find(res.interfaces, interf => interf.type === operation.interfaceType); const newOperation:OperationModel = _.find(interf.operations, op => op.name === operation.name); return new OperationModel({ ...newOperation, @@ -167,21 +174,22 @@ export class ComponentServiceNg2 { }); } + // tslint:disable-next-line:member-ordering updateInterfaceOperation(component:Component, operation:OperationModel):Observable { const operationList = { - 'interfaces': { + interfaces: { [operation.interfaceType]: { - 'type': operation.interfaceType, - 'operations': { + type: operation.interfaceType, + operations: { [operation.name]: new BEOperationModel(operation) } } } }; - return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations', operationList) - .map((res:Response) => { - const interf:InterfaceModel = _.find(res.json().interfaces, interf => interf.type === operation.interfaceType); - const newOperation:OperationModel = _.find(interf.operations, op => op.name === operation.name); + return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations', operationList) + .map((res: any) => { + const interf: InterfaceModel = _.find(res.interfaces, interf => interf.type === operation.interfaceType); + const newOperation: OperationModel = _.find(interf.operations, op => op.name === operation.name); return new OperationModel({ ...newOperation, interfaceType: interf.type, @@ -191,18 +199,16 @@ export class ComponentServiceNg2 { }); } - deleteInterfaceOperation(component:Component, operation:OperationModel):Observable { - return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaces/' + operation.interfaceId + '/operations/' + operation.uniqueId) - .map((res:Response) => { - return res.json(); - }); + + deleteInterfaceOperation(component: Component, operation:OperationModel):Observable { + return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaces/' + operation.interfaceId + '/operations/' + operation.uniqueId); } getInterfaceTypes(component:Component):Observable<{[id:string]: Array}> { - return this.http.get(this.baseUrl + 'interfaceLifecycleTypes') - .map((res:Response) => { + return this.http.get(this.baseUrl + 'interfaceLifecycleTypes') + .map((res: any) => { const interfaceMap = {}; - _.forEach(res.json(), (interf:any) => { + _.forEach(res, (interf: any) => { interfaceMap[interf.toscaPresentation.type] = _.keys(interf.toscaPresentation.operations); }); return interfaceMap; @@ -217,19 +223,18 @@ export class ComponentServiceNg2 { payloadData: oldOperation.artifactData }; - const headers = new Headers(); + const headers = new HttpHeaders(); JSON.stringify(payload); const payloadString = JSON.stringify(payload, null, ' '); const md5Result = md5(payloadString).toLowerCase(); headers.append('Content-MD5', btoa(md5Result)); return this.http.post(this.baseUrl + component.getTypeUrl() + component.uuid + '/interfaces/' + newOperation.interfaceId + '/operations/' + newOperation.uniqueId + '/artifacts/' + newOperation.implementation.artifactUUID, - payload, - {headers} - ).map((res: Response) => { - const fileName = res.json().artifactDisplayName || res.json().artifactName; + payload, {headers} + ).map((res: any) => { + const fileName = res.artifactDisplayName || res.artifactName; newOperation.artifactFileName = fileName; - return res.json(); + return res; }); } @@ -237,78 +242,17 @@ export class ComponentServiceNg2 { return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_REQUIREMENTS, COMPONENT_FIELDS.COMPONENT_CAPABILITIES]); } - createCapability(component: Component, capabilityData: Capability): Observable> { - let capBEObj = { - 'capabilities': { - [capabilityData.type]: [capabilityData] - } - }; - return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/capabilities', capBEObj) - .map((res: Response) => { - return res.json(); - }); - } - updateCapability(component: Component, capabilityData: Capability): Observable> { - let capBEObj = { - 'capabilities': { - [capabilityData.type]: [capabilityData] - } - }; - return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/capabilities', capBEObj) - .map((res: Response) => { - return res.json(); - }); - } - deleteCapability(component: Component, capId: string): Observable { - return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/capabilities/' + capId) - .map((res: Response) => { - return res.json(); - }); - } - createRequirement(component: Component, requirementData: Requirement): Observable { - let reqBEObj = { - 'requirements': { - [requirementData.capability]: [requirementData] - } - }; - return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/requirements', reqBEObj) - .map((res: Response) => { - return res.json(); - }); - } - - updateRequirement(component: Component, requirementData: Requirement): Observable { - let reqBEObj = { - 'requirements': { - [requirementData.capability]: [requirementData] - } - }; - return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/requirements', reqBEObj) - .map((res: Response) => { - return res.json(); - }); - } - - deleteRequirement(component: Component, reqId: string): Observable { - return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/requirements/' + reqId) - .map((res: Response) => { - return res.json(); - }); - } getDeploymentGraphData(component:Component):Observable { return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_RELATION, COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_GROUPS]); } createInput(component:Component, inputsToCreate:InstancePropertiesAPIMap, isSelf:boolean):Observable { - let inputs = isSelf ? { serviceProperties: inputsToCreate.componentInstanceProperties } : inputsToCreate; - return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/inputs', inputs) - .map(res => { - return res.json(); - }) + const inputs = isSelf ? { serviceProperties: inputsToCreate.componentInstanceProperties } : inputsToCreate; + return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/inputs', inputs); } createListInput(component:Component, input:any, isSelf:boolean):Observable { @@ -324,10 +268,7 @@ export class ComponentServiceNg2 { } else { inputs = input; } - return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/listInput', inputs) - .map(res => { - return res.json(); - }) + return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/listInput', inputs); } createPolicy(component:Component, policiesToCreate:InstancePropertiesAPIMap, isSelf:boolean):Observable { @@ -341,78 +282,71 @@ export class ComponentServiceNg2 { ...policiesToCreate.componentInstanceProperties } }; - return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/policies', policiesList) - .map(res => { - return res.json(); - }); + return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/policies', policiesList); } deletePolicy(component:Component, policy: PolicyInstance) { - return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/policies/' + policy.uniqueId + '/undeclare', policy) - .map(res => { - return res.json(); - }); + return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/policies/' + policy.uniqueId + '/undeclare', policy); } - restoreComponent(componentType:string, componentId:string){ + restoreComponent(componentType:string, componentId:string) { return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/restore', {}) } - archiveComponent(componentType:string, componentId:string){ + archiveComponent(componentType:string, componentId:string) { return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/archive', {}) } deleteInput(component:Component, input:InputBEModel):Observable { - return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/delete/' + input.uniqueId + '/input') - .map((res:Response) => { - return new InputBEModel(res.json()); - }); + + return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/delete/' + input.uniqueId + '/input') + .map((res) => { + return new InputBEModel(res); + }) } updateComponentInputs(component:Component, inputs:InputBEModel[]):Observable { - return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/update/inputs', inputs) - .map((res:Response) => { - return res.json().map((input) => new InputBEModel(input)); + + return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/update/inputs', inputs) + .map((res) => { + return res.map((input) => new InputBEModel(input)); }) } - filterComponentInstanceProperties(component: Component, filterData:FilterPropertiesAssignmentData): Observable {//instance-property-be-map - let params: URLSearchParams = new URLSearchParams(); + filterComponentInstanceProperties(component:Component, filterData:FilterPropertiesAssignmentData):Observable {//instance-property-be-map + let params: HttpParams = new HttpParams(); _.forEach(filterData.selectedTypes, (type:string) => { - params.append('resourceType', type); + params = params.append('resourceType', type); }); - return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/filteredproperties/' + filterData.propertyName, {search: params}) - .map((res: Response) => { - return res.json(); - }); + return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/filteredproperties/' + filterData.propertyName, {params: params}); } createServiceProperty(component: Component, propertyModel:PropertyBEModel): Observable { let serverObject = {}; serverObject[propertyModel.name] = propertyModel; return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/properties', serverObject) - .map(res => { - let property:PropertyBEModel = new PropertyBEModel(res.json()); + .map((res: PropertyBEModel) => { + const property: PropertyBEModel = new PropertyBEModel(res); return property; }) } - getServiceProperties(component: Component): Observable> { + getServiceProperties(component: Component): Observable { return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/properties') - .map((res: Response) => { - if (!res.text()){ + .map((res: PropertyBEModel[]) => { + if (!res) { return new Array(); } - return CommonUtils.initBeProperties(res.json()); + return CommonUtils.initBeProperties(res); }); } updateServiceProperties(component: Component, properties: PropertyBEModel[]) { - return this.http.put( this.baseUrl + component.getTypeUrl() + component.uniqueId + '/properties', properties) - .map((res: Response) => { - const resJson = res.json(); + return this.http.put( this.baseUrl + component.getTypeUrl() + component.uniqueId + '/properties', properties) + .map((res) => { + const resJson = res; return _.map(resJson, (resValue:PropertyBEModel) => new PropertyBEModel(resValue)); }); @@ -425,25 +359,16 @@ export class ComponentServiceNg2 { }) } - getDependencies(componentType:string, componentId: string):Observable> { - return this.http.get(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/dependencies') - .map((res:Response) => { - return res.json(); - }); + getDependencies(componentType:string, componentId: string):Observable { + return this.http.get(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/dependencies'); } - automatedUpgrade(componentType:string, componentId: string, componentsIdsToUpgrade:Array):Observable { - return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/automatedupgrade', componentsIdsToUpgrade) - .map((res:Response) => { - return res.json(); - }); + automatedUpgrade(componentType:string, componentId:string, componentsIdsToUpgrade:IAutomatedUpgradeRequestObj[]):Observable { + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/automatedupgrade', componentsIdsToUpgrade); } - updateComponentInstance(component:Component, componentInstance:ComponentInstance):Observable { - return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstance/' + componentInstance.uniqueId, componentInstance) - .map((res:Response) => { - return res.json(); - }); + updateMultipleComponentInstances(componentId:string, instances:ComponentInstance[]):Observable { + return this.http.post(this.baseUrl + componentId + '/resourceInstance/multipleComponentInstance', instances); } getServiceFilterConstraints(component:Component):Observable { @@ -451,24 +376,18 @@ export class ComponentServiceNg2 { } createServiceFilterConstraints(component:Component, componentInstance:ComponentInstance, constraint:ConstraintObject):Observable { - return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstances/' + componentInstance.uniqueId + '/nodeFilter', constraint) - .map((res:Response) => { - return res.json(); - }); + return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstances/' + componentInstance.uniqueId + '/nodeFilter', constraint); } - updateServiceFilterConstraints(component:Component, componentInstance:ComponentInstance, constraints:Array):Observable { - return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstances/' + componentInstance.uniqueId + '/nodeFilter/', constraints) - .map((res:Response) => { - return res.json(); - }); + updateServiceFilterConstraints(component:Component, componentInstance:ComponentInstance, constraints:ConstraintObject[]):Observable { + return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstances/' + componentInstance.uniqueId + '/nodeFilter/', constraints); } deleteServiceFilterConstraints(component:Component, componentInstance:ComponentInstance, constraintIndex:number) { - return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstances/' + componentInstance.uniqueId + '/nodeFilter/' + constraintIndex) - .map((res:Response) => { - return res.json(); - }); + return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/resourceInstances/' + componentInstance.uniqueId + '/nodeFilter/' + constraintIndex); } -} + protected analyzeComponentDataResponse(res: Response):ComponentGenericResponse { + return new ComponentGenericResponse().deserialize(res); + } +} diff --git a/catalog-ui/src/app/ng2/services/component-services/resource.service.ts b/catalog-ui/src/app/ng2/services/component-services/resource.service.ts index 699e762a60..d20f5415bc 100644 --- a/catalog-ui/src/app/ng2/services/component-services/resource.service.ts +++ b/catalog-ui/src/app/ng2/services/component-services/resource.service.ts @@ -21,14 +21,14 @@ import { Injectable } from '@angular/core'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/toPromise'; -import { Http, Response, Headers, RequestOptions } from '@angular/http'; +import { HttpClient } from '@angular/common/http'; @Injectable() export class ResourceServiceNg2 { protected baseUrl = ""; - constructor(private http: Http) { + constructor(private http: HttpClient) { } diff --git a/catalog-ui/src/app/ng2/services/component-services/service.service.ts b/catalog-ui/src/app/ng2/services/component-services/service.service.ts index dce4e814ec..9460a32323 100644 --- a/catalog-ui/src/app/ng2/services/component-services/service.service.ts +++ b/catalog-ui/src/app/ng2/services/component-services/service.service.ts @@ -22,9 +22,7 @@ import { Injectable, Inject } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/toPromise'; -import { Response, URLSearchParams } from '@angular/http'; -import {Service, OperationModel} from "app/models"; -import { HttpService } from '../http.service'; +import {Service} from "app/models"; import {SdcConfigToken, ISdcConfig} from "../../config/sdc-config.config"; import {ForwardingPath} from "app/models/forwarding-path"; @@ -34,77 +32,53 @@ import {Component} from "app/models/components/component"; import {ComponentGenericResponse} from "app/ng2/services/responses/component-generic-response"; import {COMPONENT_FIELDS, SERVICE_FIELDS} from "app/utils/constants"; import {ComponentServiceNg2} from "./component.service"; -import {ServiceGenericResponse} from "app/ng2/services/responses/service-generic-response"; import {ServicePathMapItem} from "app/models/graph/nodes-and-links-map"; -import {ConsumptionInput} from 'app/ng2/components/logic/service-consumption/service-consumption.component'; - +import { HttpClient, HttpParams } from '@angular/common/http'; +import { OperationModel } from '../../../models/operation'; +import { ConsumptionInput } from '../../components/logic/service-consumption/service-consumption.component'; @Injectable() export class ServiceServiceNg2 extends ComponentServiceNg2 { protected baseUrl = ""; - constructor(protected http: HttpService, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) { + constructor(protected http: HttpClient, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) { super(http, sdcConfig); this.baseUrl = sdcConfig.api.root + sdcConfig.api.component_api_root; } validateConformanceLevel(service: Service): Observable { - return this.http.get(this.baseUrl + service.getTypeUrl() + service.uuid + '/conformanceLevelValidation') - .map((res: Response) => { - return res.json(); - }); - } - - getNodesAndLinksMap(service: Service):Observable> { - return this.http.get(this.baseUrl + service.getTypeUrl() + service.uniqueId + '/linksMap').map(res => { - return >res.json(); - }); - } - - getServicePath(service: Service, id: string):Observable { - return this.http.get(this.baseUrl + service.getTypeUrl() + service.uniqueId + '/paths/' + id) - .map(res => { - return res.json(); - }) + return this.http.get(this.baseUrl + service.getTypeUrl() + service.uuid + '/conformanceLevelValidation'); } - getServicePaths(service: Service):Observable { - return this.http.get(this.baseUrl + service.getTypeUrl() + service.uniqueId + '/paths') - .map(res => { - return res.json(); - }) + getNodesAndLinksMap(serviceId: string):Observable> { + return this.http.get>(this.baseUrl + 'services/' + serviceId + '/linksMap'); } - createOrUpdateServicePath(service: Service, inputsToCreate: ForwardingPath):Observable { + createOrUpdateServicePath(serviceId: string, inputsToCreate: ForwardingPath):Observable { if (inputsToCreate.uniqueId) { - return this.updateServicePath(service, inputsToCreate); + return this.updateServicePath(serviceId, inputsToCreate); } else { - return this.createServicePath(service, inputsToCreate); + return this.createServicePath(serviceId, inputsToCreate); } } - createServicePath(service: Service, inputsToCreate: ForwardingPath):Observable { + createServicePath(serviceId: string, inputsToCreate: ForwardingPath):Observable { let input = new ServicePathRequestData(inputsToCreate); - - return this.http.post(this.baseUrl + service.getTypeUrl() + service.uniqueId + '/paths', input) - .map(res => { - return this.parseServicePathResponse(res); - }); + return this.http.post(this.baseUrl + 'services/' + serviceId + '/paths', input).map((res:any) => { + return this.parseServicePathResponse(res); + }); } - deleteServicePath(service: Service, id: string):Observable { - return this.http.delete(this.baseUrl + service.getTypeUrl() + service.uniqueId + '/paths/' + id ) - .map((res) => { - return res.json(); - }); + deleteServicePath(serviceId: string, id: string):Observable { + return this.http.delete(this.baseUrl + 'services/' + serviceId + '/paths/' + id); } - updateServicePath(service: Service, inputsToUpdate:ForwardingPath):Observable { + updateServicePath(serviceId: string, inputsToUpdate:ForwardingPath):Observable { let input = new ServicePathRequestData(inputsToUpdate); - return this.http.put(this.baseUrl + service.getTypeUrl() + service.uniqueId + '/paths', input) + return this.http.put<{[key:string]:ForwardingPath}>(this.baseUrl + 'services/' + serviceId + '/paths', input) .map((res) => { return this.parseServicePathResponse(res); }); @@ -122,28 +96,25 @@ export class ServiceServiceNg2 extends ComponentServiceNg2 { } getServiceConsumptionInputs(service: Service, serviceInstanceId: String, interfaceId: string, operation: OperationModel): Observable { - return this.http.get(this.baseUrl + service.getTypeUrl() + service.uniqueId + '/consumption/' + serviceInstanceId + '/interfaces/' + interfaceId + '/operations/' + operation.uniqueId + '/inputs') - .map(res => { - return res.json(); - }); + return this.http.get(this.baseUrl + service.getTypeUrl() + service.uniqueId + '/consumption/' + serviceInstanceId + '/interfaces/' + interfaceId + + '/operations/' + operation.uniqueId + '/inputs'); } createOrUpdateServiceConsumptionInputs(service: Service, serviceInstanceId: String, consumptionInputsList: Array<{[id: string]: Array}>): Observable { return this.http.post(this.baseUrl + service.getTypeUrl() + service.uniqueId + '/consumption/' + serviceInstanceId, consumptionInputsList); } - checkComponentInstanceVersionChange(service: Service, newVersionId: string):Observable> { - let instanceId = service.selectedInstance.uniqueId; - let queries = {componentInstanceId: instanceId, newComponentInstanceId: newVersionId}; + checkComponentInstanceVersionChange(componentType:string, componentId:string, instanceId:string, newInstanceId:string):Observable> { + let queries = {componentInstanceId: instanceId, newComponentInstanceId: newInstanceId}; - let params:URLSearchParams = new URLSearchParams(); + let params:HttpParams = new HttpParams(); _.map(_.keys(queries), (key:string):void => { - params.append(key, queries[key]); + params = params.append(key, queries[key]); }); - let url = this.baseUrl + service.getTypeUrl() + service.uniqueId + '/paths-to-delete'; - return this.http.get(url, {search: params}).map((res: Response) => { - return res.json().forwardingPathToDelete; + let url = this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/paths-to-delete'; + return this.http.get(url, {params: params}).map((res) => { + return res.forwardingPathToDelete; }); } @@ -151,12 +122,8 @@ export class ServiceServiceNg2 extends ComponentServiceNg2 { return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_RELATION, COMPONENT_FIELDS.COMPONENT_INSTANCES, SERVICE_FIELDS.FORWARDING_PATHS, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_POLICIES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_GROUPS]); } - protected analyzeComponentDataResponse(res: Response):ComponentGenericResponse { - return new ServiceGenericResponse().deserialize(res.json()); - } - - private parseServicePathResponse(res: Response):ForwardingPath { - let resJSON = res.json(); + private parseServicePathResponse(res: { [key:string]:ForwardingPath }):ForwardingPath { + let resJSON = res; let pathId = Object.keys(resJSON.forwardingPaths)[0]; let forwardingPath = resJSON.forwardingPaths[pathId]; let path:ForwardingPath = new ForwardingPath(); diff --git a/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts b/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts new file mode 100644 index 0000000000..0abb163404 --- /dev/null +++ b/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts @@ -0,0 +1,515 @@ +/** + * Created by ob0695 on 6/26/2018. + */ +/*- + * ============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========================================================= + */ + +import * as _ from "lodash"; +import {Injectable, Inject} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/toPromise'; +import { + Component, + InputBEModel, + InstancePropertiesAPIMap, + FilterPropertiesAssignmentData, + ArtifactModel, + PropertyModel, + IFileDownload, + AttributeModel, + IAttributeModel, Capability, Requirement +} from "app/models"; +import {ArtifactGroupType, COMPONENT_FIELDS} from "app/utils"; +import {ComponentGenericResponse} from "../responses/component-generic-response"; +import {InstanceBePropertiesMap} from "../../../models/properties-inputs/property-fe-map"; +import {API_QUERY_PARAMS} from "app/utils"; +import {ComponentType, ServerTypeUrl, SERVICE_FIELDS} from "../../../utils/constants"; +import {SdcConfigToken, ISdcConfig} from "../../config/sdc-config.config"; +import {IDependenciesServerResponse} from "../responses/dependencies-server-response"; +import {AutomatedUpgradeGenericResponse} from "../responses/automated-upgrade-response"; +import {IAutomatedUpgradeRequestObj} from "../../pages/automated-upgrade/automated-upgrade.service"; +import {ComponentInstance} from "../../../models/componentsInstances/componentInstance"; +import {CommonUtils} from "../../../utils/common-utils"; +import {RelationshipModel} from "../../../models/graph/relationship"; +import {ServiceGenericResponse} from "../responses/service-generic-response"; +import { HttpClient, HttpParams, HttpHeaders } from "@angular/common/http"; +import { HttpHelperService } from "../http-hepler.service"; +import { + Component as TopologyTemplate, + FullComponentInstance, + Service, + OperationModel, +} from 'app/models'; +import { ConsumptionInput } from "../../components/logic/service-consumption/service-consumption.component"; +import { ConstraintObject } from "../../components/logic/service-dependencies/service-dependencies.component"; +import { ComponentMetadata } from "../../../models/component-metadata"; +import { PolicyInstance } from "../../../models/graph/zones/policy-instance"; +import { PropertyBEModel } from "../../../models/properties-inputs/property-be-model"; + +/* we need to use this service from now, we will remove component.service when we finish remove the angular1. + The service is duplicated since we can not use downgrades service with NGXS*/ + +@Injectable() +export class TopologyTemplateService { + + protected baseUrl; + + constructor(protected http: HttpClient, @Inject(SdcConfigToken) sdcConfig: ISdcConfig) { + this.baseUrl = sdcConfig.api.root + sdcConfig.api.component_api_root; + } + + getFullComponent(componentType: string, uniqueId: string): Observable { + return this.http.get(this.baseUrl + this.getServerTypeUrl(componentType) + uniqueId); + } + + getComponentMetadata(uniqueId: string, type: string): Observable { + return this.getComponentDataByFieldsName(type, uniqueId, [COMPONENT_FIELDS.COMPONENT_METADATA]); + } + + getComponentInstanceAttributesAndProperties(uniqueId: string, type: string): Observable { + return this.getComponentDataByFieldsName(type, uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES, COMPONENT_FIELDS.COMPONENT_INSTANCES_ATTRIBUTES]); + } + + async getComponentAttributes(componentType: string, componentId: string): Promise { + return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_ATTRIBUTES]).toPromise(); + } + + getComponentCompositionData(componentUniqueId: string, componentType: string): Observable { + const params: string[] = [COMPONENT_FIELDS.COMPONENT_INSTANCES_RELATION, COMPONENT_FIELDS.COMPONENT_INSTANCES, + COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_POLICIES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_GROUPS]; + if (componentType === ComponentType.SERVICE) { + params.push(COMPONENT_FIELDS.FORWARDING_PATHS); + } + return this.getComponentDataByFieldsName(componentType, componentUniqueId, params); + } + + getComponentResourcePropertiesData(component: Component): Observable { + return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, + [COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_POLICIES, COMPONENT_FIELDS.COMPONENT_NON_EXCLUDED_GROUPS]); + } + + getComponentResourceInstances(component: Component): Observable { + return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INSTANCES]); + } + + getComponentInputs(component: Component): Observable { + return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INPUTS]); + } + + getComponentInputsWithProperties(componentType: string, componentId: string): Observable { + return this.getComponentDataByFieldsName(componentType, componentId, + [COMPONENT_FIELDS.COMPONENT_INPUTS, COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES, COMPONENT_FIELDS.COMPONENT_PROPERTIES]); + } + + getComponentDeploymentArtifacts(component: Component): Observable { + return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_DEPLOYMENT_ARTIFACTS]); + } + + getComponentInformationalArtifacts(component: Component): Observable { + return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INFORMATIONAL_ARTIFACTS]); + } + + getComponentInformationalArtifactsAndInstances(component: Component): Observable { + return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INFORMATIONAL_ARTIFACTS, COMPONENT_FIELDS.COMPONENT_INSTANCES]); + } + + getComponentToscaArtifacts(componentType: string, componentId: string): Observable { + return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_TOSCA_ARTIFACTS]); + } + + getComponentProperties(component: Component): Observable { + return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_PROPERTIES]); + } + + getCapabilitiesAndRequirements(componentType: string, componentId: string): Observable { + return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_REQUIREMENTS, COMPONENT_FIELDS.COMPONENT_CAPABILITIES]); + } + + getRequirementsAndCapabilitiesWithProperties(componentType: string, componentId: string): Observable { + return this.getComponentDataByFieldsName(componentType, componentId, + [COMPONENT_FIELDS.COMPONENT_REQUIREMENTS, COMPONENT_FIELDS.COMPONENT_CAPABILITIES, COMPONENT_FIELDS.COMPONENT_CAPABILITIES_PROPERTIES]); + } + + getDeploymentGraphData(componentType: string, componentId: string): Observable { + return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_RELATION, COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_GROUPS]); + } + + createInput(component: Component, inputsToCreate: InstancePropertiesAPIMap, isSelf: boolean): Observable { + const inputs = isSelf ? { serviceProperties: inputsToCreate.componentInstanceProperties } : inputsToCreate; + return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/inputs', inputs); + } + + restoreComponent(componentType: string, componentId: string) { + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/restore', {}); + } + + archiveComponent(componentType: string, componentId: string) { + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/archive', {}); + } + + deleteInput(component: Component, input: InputBEModel): Observable { + return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/delete/' + input.uniqueId + '/input') + .map((res) => { + return new InputBEModel(res); + }); + } + + updateComponentInputs(component: Component, inputs: InputBEModel[]): Observable { + return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/update/inputs', inputs) + .map((res) => { + return res.map((input) => new InputBEModel(input)); + }); + } + + filterComponentInstanceProperties(component: Component, filterData: FilterPropertiesAssignmentData): Observable {// instance-property-be-map + let params: HttpParams = new HttpParams(); + _.forEach(filterData.selectedTypes, (type: string) => { + params = params.append('resourceType', type); + }); + + // tslint:disable-next-line:object-literal-shorthand + return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/filteredproperties/' + filterData.propertyName, {params: params}); + } + + createServiceProperty(componentId: string, propertyModel: PropertyBEModel): Observable { + const serverObject = {}; + serverObject[propertyModel.name] = propertyModel; + return this.http.post(this.baseUrl + 'services/' + componentId + '/properties', serverObject) + .map((res) => { + const property: PropertyBEModel = new PropertyBEModel(res); + return property; + }); + } + + getServiceProperties(componentId: string): Observable { + return this.http.get(this.baseUrl + 'services/' + componentId + '/properties') + .map((res) => { + if (!res) { + return new Array(); + } + return CommonUtils.initBeProperties(res); + }); + } + + updateServiceProperties(componentId: string, properties: PropertyBEModel[]) { + return this.http.put( this.baseUrl + 'services/' + componentId + '/properties', properties) + .map((res) => { + const resJson = res; + return _.map(resJson, + (resValue: PropertyBEModel) => new PropertyBEModel(resValue)); + }); + } + + deleteServiceProperty(componentId: string, property: PropertyBEModel): Observable { + return this.http.delete(this.baseUrl + 'services/' + componentId + '/properties/' + property.uniqueId ) + .map((res: Response) => { + return property.uniqueId; + }); + } + + getDependencies(componentType: string, componentId: string): Observable { + return this.http.get(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/dependencies'); + } + + automatedUpgrade(componentType: string, componentId: string, componentsIdsToUpgrade: IAutomatedUpgradeRequestObj[]): Observable { + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/automatedupgrade', componentsIdsToUpgrade); + } + + updateComponentInstance(componentMetaDataId: string, componentInstance:ComponentInstance): Observable { + return this.http.post(this.baseUrl + 'services/' + componentMetaDataId + '/resourceInstance/' + componentInstance.uniqueId, componentInstance); + } + + updateMultipleComponentInstances(componentId: string, componentType: string, instances: ComponentInstance[]): Observable { + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance/multipleComponentInstance', instances) + .map((res) => { + return CommonUtils.initComponentInstances(res); + }); + } + + createRelation(componentId: string, componentType: string, link: RelationshipModel): Observable { + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance/associate', link) + .map((res) => { + return new RelationshipModel(res); + }); + } + + deleteRelation(componentId: string, componentType: string, link: RelationshipModel): Observable { + return this.http.put(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance/dissociate', link) + .map((res) => { + return new RelationshipModel(res); + }); + } + + createComponentInstance(componentType: string, componentId: string, componentInstance: ComponentInstance): Observable { + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance', componentInstance) + .map((res) => { + return new ComponentInstance(res); + }); + } + + deleteComponentInstance(componentType: string, componentId: string, componentInstanceId: string): Observable { + return this.http.delete(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/resourceInstance/' + componentInstanceId) + .map((res) => { + return new ComponentInstance(res); + }); + } + + fetchRelation(componentType: string, componentId: string, linkId: string): Observable { + return this.http.get(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/relationId/' + linkId) + .map((res) => { + return new RelationshipModel(res); + }); + } + + addOrUpdateArtifact = (componentType: string, componentId: string, artifact: ArtifactModel): Observable => { + let headerObj: HttpHeaders = new HttpHeaders(); + if (artifact.payloadData) { + headerObj = headerObj.append('Content-MD5', HttpHelperService.getHeaderMd5(artifact)); + } + + let artifactID: string = ''; + if (artifact.uniqueId) { + artifactID = '/' + artifact.uniqueId; + } + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/artifacts' + artifactID, JSON.stringify(artifact), {headers: headerObj}).map( + (res) => new ArtifactModel(res) + ); + } + + deleteArtifact = (componentId: string, componentType: string, artifactId: string, artifactLabel: string): Observable => { + return this.http.delete(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/artifacts/' + artifactId + '?operation=' + artifactLabel) + .map((res) => new ArtifactModel(res)); + } + + downloadArtifact = (componentType: string, componentId: string, artifactId: string): Observable => { + return this.http.get(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/artifacts/' + artifactId); + } + + // ------------------------------------------------ Properties API --------------------------------------------------// + addProperty = (componentType: string, componentId: string, property: PropertyModel):Observable => { + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/properties', property.convertToServerObject()).map((response) => { + return new PropertyModel(response[Object.keys(response)[0]]); + }); + } + + updateProperty = (componentType: string, componentId: string, property: PropertyModel): Observable => { + var propertiesList:PropertyBEModel[] = [property]; + return this.http.put(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/properties', propertiesList) + .map((response) => { + return new PropertyModel(response[Object.keys(response)[0]]); + }); + } + + deleteProperty = (componentType: string, componentId: string, propertyId: string): Observable => { + return this.http.delete(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/properties/' + propertyId); + } + + // ------------------------------------------------ Attributes API --------------------------------------------------// + addAttribute = (componentType: string, componentId: string, attribute: AttributeModel): Observable => { + return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/attributes', attribute.convertToServerObject()) + .map((response) => { + return new AttributeModel(response); + }); + } + + updateAttribute = (componentType: string, componentId: string, attribute: AttributeModel): Observable => { + const payload = attribute.convertToServerObject(); + + return this.http.put(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/attributes/' + attribute.uniqueId, payload) + .map((response) => { + return new AttributeModel(response); + }); + } + + // Async Methods + addAttributeAsync = async (componentType: string, componentId: string, attribute: AttributeModel): Promise => { + return this.addAttribute(componentType, componentId, attribute).toPromise(); + } + + updateAttributeAsync = async (componentType: string, componentId: string, attribute: AttributeModel): Promise => { + return this.updateAttribute(componentType, componentId, attribute).toPromise(); + } + + deleteAttributeAsync = async (componentType: string, componentId: string, attribute: AttributeModel): Promise => { + return this.http.delete(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/attributes/' + attribute.uniqueId, {}).toPromise(); + } + + getArtifactsByType(componentType: string, componentId: string, artifactsType: ArtifactGroupType) { + return this.getComponentDataByFieldsName(componentType, componentId, [this.convertArtifactTypeToUrl(artifactsType)]); + } + + getServiceConsumptionData(componentType: string, componentId: string): Observable { + return this.getComponentDataByFieldsName(componentType, componentId, [ + // COMPONENT_FIELDS.COMPONENT_INSTANCES_INTERFACES, + COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES, + // COMPONENT_FIELDS.COMPONENT_INSTANCES_INPUTS, + COMPONENT_FIELDS.COMPONENT_INPUTS, + COMPONENT_FIELDS.COMPONENT_INSTANCES, + COMPONENT_FIELDS.COMPONENT_CAPABILITIES + ]); + } + + getServiceConsumptionInputs(componentMetaDataId: string, serviceInstanceId: string, interfaceId: string, operation: OperationModel): Observable { + return this.http.get + (this.baseUrl + 'services/' + componentMetaDataId + '/consumption/' + serviceInstanceId + '/interfaces/' + interfaceId + '/operations/' + operation.uniqueId + '/inputs'); + } + + createOrUpdateServiceConsumptionInputs(componentMetaDataId: string, serviceInstanceId: string, consumptionInputsList: Array<{[id: string]: ConsumptionInput[]}>): Observable { + return this.http.post(this.baseUrl + 'services/' + componentMetaDataId + '/consumption/' + serviceInstanceId, consumptionInputsList); + } + + getServiceFilterConstraints(componentType: string, componentId: string): Observable { + return this.getComponentDataByFieldsName(componentType, componentId, [SERVICE_FIELDS.NODE_FILTER]); + } + + getComponentInstanceProperties(componentType: string, componentId: string): Observable { + return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES]); + } + + createServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: ConstraintObject): Observable { + return this.http.post(this.baseUrl + 'services/' + componentMetaDataId + '/resourceInstances/' + componentInstanceId + '/nodeFilter', constraint); + } + + updateServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraints: ConstraintObject[]):Observable { + return this.http.put(this.baseUrl + 'services/' + componentMetaDataId + '/resourceInstances/' + componentInstanceId + '/nodeFilter', constraints) + } + + deleteServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraintIndex: number): Observable{ + return this.http.delete(this.baseUrl + 'services/' + componentMetaDataId + '/resourceInstances/' + componentInstanceId + '/nodeFilter/' + constraintIndex) + } + + deletePolicy(component: Component, policy: PolicyInstance): Observable { + return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/policies/' + policy.uniqueId + '/undeclare', policy) + } + + createListInput(componentId: string, input: any, isSelf: boolean): Observable { + let inputs: any; + if (isSelf) { + // change componentInstanceProperties -> serviceProperties + inputs = { + componentInstInputsMap: { + serviceProperties: input.componentInstInputsMap.componentInstanceProperties + }, + listInput: input.listInput + }; + } else { + inputs = input; + } + return this.http.post(this.baseUrl + 'services/' + componentId + '/create/listInput', inputs); + } + + createPolicy(component: Component, policiesToCreate: InstancePropertiesAPIMap, isSelf: boolean): Observable { + const policiesList = + isSelf ? + // tslint:disable-next-line:object-literal-key-quotes + {'componentPropertiesToPolicies': { + ...policiesToCreate.componentInstanceProperties + } + } : + // tslint:disable-next-line:object-literal-key-quotes + {'componentInstancePropertiesToPolicies': { + ...policiesToCreate.componentInstanceProperties + } + }; + return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/create/policies', policiesList); + } + + protected getComponentDataByFieldsName(componentType: string, componentId: string, fields: string[]): Observable { + let params: HttpParams = new HttpParams(); + _.forEach(fields, (field: string): void => { + params = params.append(API_QUERY_PARAMS.INCLUDE, field); + }); + // tslint:disable-next-line:object-literal-shorthand + return this.http.get(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/filteredDataByParams', {params: params}) + .map((res) => { + return componentType === ComponentType.SERVICE ? new ServiceGenericResponse().deserialize(res) : + new ComponentGenericResponse().deserialize(res); + }); + } + + private getServerTypeUrl = (componentType: string): string => { + switch (componentType) { + case ComponentType.SERVICE: + case ComponentType.SERVICE_PROXY: + return ServerTypeUrl.SERVICES; + default: + return ServerTypeUrl.RESOURCES; + } + } + + private convertArtifactTypeToUrl = (artifactType: ArtifactGroupType): string => { + switch (artifactType) { + case ArtifactGroupType.TOSCA: + return COMPONENT_FIELDS.COMPONENT_TOSCA_ARTIFACTS; + case ArtifactGroupType.INFORMATION: + return COMPONENT_FIELDS.COMPONENT_INFORMATIONAL_ARTIFACTS; + case ArtifactGroupType.DEPLOYMENT: + return COMPONENT_FIELDS.COMPONENT_DEPLOYMENT_ARTIFACTS; + case ArtifactGroupType.SERVICE_API: + return COMPONENT_FIELDS.SERVICE_API_ARTIFACT; + } + } + + // createCapability(component: Component, capabilityData: Capability): Observable { + createCapability(type: string, uniqueId: string, capabilityData: Capability): Observable { + let capBEObj = { + 'capabilities': { + [capabilityData.type]: [capabilityData] + } + }; + return this.http.post(this.baseUrl + type + uniqueId + '/capabilities', capBEObj); + } + + updateCapability(type: string, uniqueId: string, capabilityData: Capability): Observable { + let capBEObj = { + 'capabilities': { + [capabilityData.type]: [capabilityData] + } + }; + return this.http.put(this.baseUrl + type + uniqueId + '/capabilities', capBEObj); + } + + deleteCapability(component: Component, capId: string): Observable { + return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/capabilities/' + capId); + } + + createRequirement(type: string, uniqueId: string, requirementData: Requirement): Observable { + let reqBEObj = { + 'requirements': { + [requirementData.capability]: [requirementData] + } + }; + return this.http.post(this.baseUrl + type + uniqueId + '/requirements', reqBEObj); + } + + updateRequirement(type: string, uniqueId: string, requirementData: Requirement): Observable { + let reqBEObj = { + 'requirements': { + [requirementData.capability]: [requirementData] + } + }; + return this.http.put(this.baseUrl + type + uniqueId + '/requirements', reqBEObj); + } + + deleteRequirement(component: Component, reqId: string): Observable { + return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/requirements/' + reqId); + } +} diff --git a/catalog-ui/src/app/ng2/services/config.service.ts b/catalog-ui/src/app/ng2/services/config.service.ts index 11fe395811..2b9b49cf62 100644 --- a/catalog-ui/src/app/ng2/services/config.service.ts +++ b/catalog-ui/src/app/ng2/services/config.service.ts @@ -16,62 +16,80 @@ * */ -import { Injectable, Inject } from '@angular/core'; -import { Http, Response } from '@angular/http'; +import { HttpClient } from '@angular/common/http'; +import { Inject, Injectable, Injector } from '@angular/core'; +import { IAppConfigurtaion, Plugins, PluginsConfiguration, ValidationConfiguration, Validations } from 'app/models'; +import { IApi } from 'app/models/app-config'; import 'rxjs/add/operator/toPromise'; -import {IAppConfigurtaion, ValidationConfiguration, Validations, Plugins, PluginsConfiguration} from "app/models"; -import {IApi} from "app/models/app-config"; -import {SdcConfigToken, ISdcConfig} from "../config/sdc-config.config"; +import { ISdcConfig, SdcConfigToken } from '../config/sdc-config.config'; +import { CacheService } from './cache.service'; @Injectable() export class ConfigService { - private baseUrl; public configuration: IAppConfigurtaion; - public api:IApi; + public api: IApi; + private baseUrl; + + constructor( + @Inject(SdcConfigToken) private sdcConfig: ISdcConfig, + private cacheService: CacheService, + private injector: Injector, + private http: HttpClient + ) { + this.api = this.sdcConfig.api; + this.baseUrl = this.api.root + this.sdcConfig.api.component_api_root; + } - constructor(private http: Http, @Inject(SdcConfigToken) private sdcConfig:ISdcConfig) { - this.api = this.sdcConfig.api; - this.baseUrl = this.api.root + this.sdcConfig.api.component_api_root; + loadSdcSetupData = (): Promise => { + const url: string = this.api.root + this.api.GET_SDC_Setup_Data; + const promise: Promise = this.http.get(url).toPromise(); + promise.then((response) => { + this.cacheService.set('version', response.version); + this.cacheService.set('serviceCategories', response.categories.serviceCategories); + this.cacheService.set('resourceCategories', response.categories.resourceCategories); + this.cacheService.set('UIConfiguration', response.configuration); + }); + return promise; } loadValidationConfiguration(): Promise { - let url: string = this.sdcConfig.validationConfigPath; - let promise: Promise = this.http.get(url).map((res: Response) => res.json()).toPromise(); + const url: string = this.sdcConfig.validationConfigPath; + const promise: Promise = this.http.get(url).toPromise(); promise.then((validationData: Validations) => { ValidationConfiguration.validation = validationData; + this.cacheService.set('validation', validationData); }).catch((ex) => { console.error('Error loading validation.json configuration file, using fallback data', ex); - let fallback:Validations = { - "propertyValue": { - "max": 2500, - "min": 0 + const fallback = { + propertyValue: { + max: 2500, + min: 0 }, - - "validationPatterns": { - "string": "^[\\sa-zA-Z0-9+-]+$", - "comment": "^[\\sa-zA-Z0-9+-_\\{\\}\"]+$", - "integer": "^(([-+]?\\d+)|([-+]?0x[0-9a-fA-F]+))$" + validationPatterns: { + string: '^[\\sa-zA-Z0-9+-]+$', + stringOrEmpty: '^[\\sa-zA-Z0-9&-]*$', + comment: '^[\\sa-zA-Z0-9+-_\\{\\}"]+$', + integer: '^(([-+]?\\d+)|([-+]?0x[0-9a-fA-F]+))$' } }; - ValidationConfiguration.validation = fallback; - + this.cacheService.set('validation', fallback); }); return promise; } - loadPluginsConfiguration(): Promise { - let url:string = this.api.no_proxy_root + this.api.GET_plugins_configuration; - let promise: Promise = this.http.get(url).map((res: Response) => res.json()).toPromise(); + loadPluginsConfiguration = (): Promise => { + const url: string = this.api.no_proxy_root + this.api.GET_plugins_configuration; + const promise: Promise = this.http.get(url).toPromise(); return new Promise((resolve) => { promise.then((pluginsData: Plugins) => { PluginsConfiguration.plugins = pluginsData; resolve(); }).catch((ex) => { - console.error("Error loading plugins configuration from FE", ex); + console.error('Error loading plugins configuration from FE', ex); PluginsConfiguration.plugins = [] as Plugins; resolve(); diff --git a/catalog-ui/src/app/ng2/services/cookie.service.ts b/catalog-ui/src/app/ng2/services/cookie.service.ts index 2a783fdd48..61d13186fa 100644 --- a/catalog-ui/src/app/ng2/services/cookie.service.ts +++ b/catalog-ui/src/app/ng2/services/cookie.service.ts @@ -19,7 +19,7 @@ */ import {Injectable, Inject} from '@angular/core'; -import {IAppConfigurtaion, ICookie} from "../../models/app-config"; +import {ICookie} from "../../models/app-config"; import {SdcConfigToken, ISdcConfig} from "../config/sdc-config.config"; @Injectable() diff --git a/catalog-ui/src/app/ng2/services/data-type.service.ts b/catalog-ui/src/app/ng2/services/data-type.service.ts index cabaccd1d5..0559f35ae2 100644 --- a/catalog-ui/src/app/ng2/services/data-type.service.ts +++ b/catalog-ui/src/app/ng2/services/data-type.service.ts @@ -20,9 +20,9 @@ import * as _ from "lodash"; import { Injectable } from '@angular/core'; -import { DataTypeModel, DataTypesMap, PropertyBEModel, PropertyFEModel, DerivedFEProperty, DerivedFEPropertyMap } from "app/models"; +import { DataTypeModel, DataTypesMap, PropertyFEModel, DerivedFEProperty} from "app/models"; import { DataTypesService } from "app/services/data-types-service"; -import { PROPERTY_DATA, PROPERTY_TYPES } from "app/utils"; +import { PROPERTY_DATA } from "app/utils"; /** This is a new service for NG2, to eventually replace app/services/data-types-service.ts * @@ -32,13 +32,16 @@ import { PROPERTY_DATA, PROPERTY_TYPES } from "app/utils"; @Injectable() export class DataTypeService { - private dataTypes: DataTypesMap; + public dataTypes: DataTypesMap; constructor(private dataTypeService: DataTypesService) { this.dataTypes = dataTypeService.getAllDataTypes(); //This should eventually be replaced by an NG2 call to the backend instead of utilizing Angular1 downgraded component. } public getDataTypeByTypeName(typeName: string): DataTypeModel { + if(!this.dataTypes){ + this.dataTypes = this.dataTypeService.getAllDataTypes(); + } if (!this.dataTypes[typeName]) console.log("MISSING Datatype: " + typeName); return this.dataTypes[typeName]; } @@ -47,6 +50,13 @@ export class DataTypeService { return this.dataTypes; } + public getConstraintsByParentTypeAndUniqueID(rootPropertyType, propertyName){ + // const property = this.dataTypes[rootPropertyType].properties.filter(property => + // property.name == propertyName); + // return property[0] && property[0].constraints ? property[0].constraints[0].validValues : null; + return null; + } + public getDerivedDataTypeProperties(dataTypeObj: DataTypeModel, propertiesArray: Array, parentName: string) { //push all child properties to array diff --git a/catalog-ui/src/app/ng2/services/event-bus.service.ts b/catalog-ui/src/app/ng2/services/event-bus.service.ts index cc53d7978b..2a15ca25db 100644 --- a/catalog-ui/src/app/ng2/services/event-bus.service.ts +++ b/catalog-ui/src/app/ng2/services/event-bus.service.ts @@ -1,5 +1,5 @@ import {Injectable} from '@angular/core'; -import {BasePubSub, IPubSubEvent} from 'sdc-pubsub'; +import {BasePubSub, IPubSubEvent} from "sdc-pubsub"; @Injectable() export class EventBusService extends BasePubSub { diff --git a/catalog-ui/src/app/ng2/services/file-utils.service.ts b/catalog-ui/src/app/ng2/services/file-utils.service.ts new file mode 100644 index 0000000000..57897492b0 --- /dev/null +++ b/catalog-ui/src/app/ng2/services/file-utils.service.ts @@ -0,0 +1,48 @@ +import { Injectable } from "@angular/core"; +import { WindowRef } from "./window.service"; + +@Injectable() +export class FileUtilsService { + constructor(private windowRef: WindowRef){} + + 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.windowRef.nativeWindow.URL.createObjectURL(blob); + let downloadLink = document.createElement("a"); + + downloadLink.setAttribute('href', url); + downloadLink.setAttribute('download', fileName); + document.body.appendChild(downloadLink); + + var clickEvent = new MouseEvent("click", { + "view": window, + "bubbles": true, + "cancelable": true + }); + downloadLink.dispatchEvent(clickEvent); + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/services/gab.service.ts b/catalog-ui/src/app/ng2/services/gab.service.ts index d903d20ade..b62c566dd6 100644 --- a/catalog-ui/src/app/ng2/services/gab.service.ts +++ b/catalog-ui/src/app/ng2/services/gab.service.ts @@ -18,12 +18,13 @@ * ============LICENSE_END========================================================= */ -import {Injectable, Inject} from "@angular/core"; -import {Response} from '@angular/http'; -import {HttpService} from "./http.service"; -import {SdcConfigToken, ISdcConfig} from "../config/sdc-config.config"; -import {Observable} from "rxjs"; +import { HttpClient } from '@angular/common/http'; +import { Inject, Injectable } from '@angular/core'; +import { Response } from '@angular/http'; +import { Observable } from 'rxjs'; +import { ISdcConfig, SdcConfigToken } from '../config/sdc-config.config'; +// tslint:disable-next-line:interface-name export interface IServerResponse { data: [{ [key: string]: string }]; } @@ -36,24 +37,25 @@ export class GabRequest { } } +// tslint:disable-next-line:max-classes-per-file @Injectable() export class GabService { baseUrl: string; gabUrl: string; - constructor(@Inject(SdcConfigToken) sdcConfig: ISdcConfig, private http: HttpService) { + constructor(@Inject(SdcConfigToken) sdcConfig: ISdcConfig, protected http: HttpClient) { this.baseUrl = sdcConfig.api.root; this.gabUrl = sdcConfig.api.POST_GAB_Search; } public getArtifact(artifactUniqueId: string, resourceId: string, columns: string[]): Observable { - let finalUrl: string = this.baseUrl + this.gabUrl; - let request: GabRequest = { + const finalUrl: string = this.baseUrl + this.gabUrl; + const request: GabRequest = { fields: columns, parentId: resourceId, - artifactUniqueId: artifactUniqueId + artifactUniqueId }; - return this.http.post(finalUrl, request); + return this.http.post(finalUrl, request); } } \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/services/groups.service.ts b/catalog-ui/src/app/ng2/services/groups.service.ts index e3b3d85b50..8b2bcd3415 100644 --- a/catalog-ui/src/app/ng2/services/groups.service.ts +++ b/catalog-ui/src/app/ng2/services/groups.service.ts @@ -1,11 +1,11 @@ import {IZoneInstanceAssignment} from '../../models/graph/zones/zone-instance'; import {Injectable, Inject} from "@angular/core"; import {Observable} from "rxjs/Observable"; -import {HttpService} from "./http.service"; import {SdcConfigToken, ISdcConfig} from "../config/sdc-config.config"; import {GroupInstance} from '../../models/graph/zones/group-instance'; import {UiBaseObject} from "../../models/ui-models/ui-base-object"; import {IZoneService} from "../../models/graph/zones/zone"; +import { HttpClient } from '@angular/common/http'; @Injectable() export class GroupsService implements IZoneService { @@ -17,13 +17,13 @@ export class GroupsService implements IZoneService { 'SERVICE': 'services' } - constructor(private http:HttpService, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) { + constructor(private http: HttpClient, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) { this.baseUrl = sdcConfig.api.root; } - public createGroupInstance(componentType:string, componentUniqueId:string, groupType:string) { - return this.http.post(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[componentType.toUpperCase()] + '/' + componentUniqueId + '/groups/' + groupType, {}).map(resp => { - return resp.json(); + public createGroupInstance(componentType:string, componentUniqueId:string, groupType:string): Observable{ + return this.http.post(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[componentType.toUpperCase()] + '/' + componentUniqueId + '/groups/' + groupType, {}).map(resp => { + return new GroupInstance(resp); }); }; @@ -40,8 +40,7 @@ export class GroupsService implements IZoneService { } public updateGroupMembers(topologyTemplateType:string, topologyTemplateId:string, groupId:string, members:Array):Observable> { - return this.http.post(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/groups/' + groupId + '/members', members) - .map(response => response.json()); + return this.http.post>(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/groups/' + groupId + '/members', members); } public updateMembers(topologyTemplateType:string, topologyTemplateId:string, groupId:string, members:Array):Observable> { @@ -50,22 +49,18 @@ export class GroupsService implements IZoneService { } public getSpecificGroup(topologyTemplateType:string, topologyTemplateId:string, groupId:string):Observable { - return this.http.get(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/groups/' + groupId) + return this.http.get(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/groups/' + groupId) .map(res => { - return new GroupInstance(res.json()); + return new GroupInstance(res); }); } public updateName(topologyTemplateType:string, topologyTemplateId:string, groupId:string, newName:string):Observable { - return this.http.put(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/groups/' + groupId, {name: newName}).map(resp => { - return resp.json(); - }); + return this.http.put(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/groups/' + groupId, {name: newName}); }; public deleteGroup(topologyTemplateType:string, topologyTemplateId:string, groupId:string) { - return this.http.delete(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/groups/' + groupId).map(resp => { - return resp.json(); - }); + return this.http.delete(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/groups/' + groupId); }; public updateZoneInstanceAssignments(topologyTemplateType:string, topologyTemplateId:string, policyId:string, members:Array):Observable { @@ -75,4 +70,6 @@ export class GroupsService implements IZoneService { public deleteZoneInstance(topologyTemplateType:string, topologyTemplateId:string, policyId:string):Observable { return this.deleteGroup(topologyTemplateType, topologyTemplateId, policyId); }; -} \ No newline at end of file + + +} diff --git a/catalog-ui/src/app/ng2/services/home.service.ts b/catalog-ui/src/app/ng2/services/home.service.ts new file mode 100644 index 0000000000..c472aa80c1 --- /dev/null +++ b/catalog-ui/src/app/ng2/services/home.service.ts @@ -0,0 +1,74 @@ +/*- + * ============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========================================================= + */ +import { HttpClient } from '@angular/common/http'; +import { Inject, Injectable } from '@angular/core'; +import { Component, IApi, Resource, Service } from 'app/models'; +import { ComponentFactory } from 'app/utils/component-factory'; +import { Observable } from 'rxjs'; +import { ISdcConfig, SdcConfigToken } from '../config/sdc-config.config'; +import { SharingService } from './sharing.service'; + +// tslint:disable-next-line:interface-name +interface IComponentsArray { + services: Service[]; + resources: Resource[]; +} + +@Injectable() +export class HomeService { + private api: IApi; + private smallObjectAttributes = [ + 'uniqueId', 'name', 'componentType', 'resourceType', 'lastUpdateDate', 'lifecycleState', 'distributionStatus', + 'icon', 'version' + ]; + + constructor(private http: HttpClient, + @Inject(SdcConfigToken) private sdcConfig: ISdcConfig, + private sharingService: SharingService, + private componentFactory: ComponentFactory) { + this.api = sdcConfig.api; + } + + public getAllComponents(smallObjects?: boolean): Observable { + return this.http.get(this.api.root + this.api.GET_element) + .map((response) => { + const componentResponse: IComponentsArray = response; + let componentsList: Component[] = []; + + componentResponse.services && componentResponse.services.forEach((serviceResponse: Service) => { + serviceResponse = (smallObjects) ? _.pick(serviceResponse, this.smallObjectAttributes) : serviceResponse; + const component: Service = this.componentFactory.createService(serviceResponse); + componentsList.push(component); + this.sharingService.addUuidValue(component.uniqueId, component.uuid); + }); + + componentResponse.resources && componentResponse.resources.forEach((resourceResponse: Resource) => { + resourceResponse = (smallObjects) ? _.pick(resourceResponse, this.smallObjectAttributes) : resourceResponse; + const component: Resource = this.componentFactory.createResource(resourceResponse); + componentsList.push(component); + this.sharingService.addUuidValue(component.uniqueId, component.uuid); + }); + + componentsList = _.orderBy(componentsList, ['lastUpdateDate'], ['desc']); + + return componentsList; + }); + } +} diff --git a/catalog-ui/src/app/ng2/services/http-hepler.service.ts b/catalog-ui/src/app/ng2/services/http-hepler.service.ts new file mode 100644 index 0000000000..2b11067a24 --- /dev/null +++ b/catalog-ui/src/app/ng2/services/http-hepler.service.ts @@ -0,0 +1,31 @@ +import { Injectable, Inject } from "@angular/core"; +import { Dictionary } from "../../utils/dictionary/dictionary"; +import { SharingService } from "../services/sharing.service"; +import { SdcConfigToken, ISdcConfig } from "../config/sdc-config.config"; + + +@Injectable() +export class HttpHelperService { + constructor( private sharingService: SharingService, + @Inject(SdcConfigToken) private sdcConfig: ISdcConfig){} + + public getUuidValue = (url: string): string => { + let map: Dictionary = this.sharingService.getUuidMap(); + if (map && url.indexOf(this.sdcConfig.api.root) > 0) { + map.forEach((key: string) => { + if (url.indexOf(key) !== -1) { + return this.sharingService.getUuidValue(key); + } + }); + } + return ''; + } + public static replaceUrlParams(url: string, urlParams: { [index: string]: any }): string { + return url.replace(/:(\w+)/g, (m, p1): string => urlParams[p1] || ''); + } + public static getHeaderMd5 = (object:any):string => { + let componentString:string = JSON.stringify(object); + let md5Result = md5(componentString).toLowerCase(); + return btoa(md5Result); + }; +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/services/http.service.ts b/catalog-ui/src/app/ng2/services/http.service.ts deleted file mode 100644 index 2785688ace..0000000000 --- a/catalog-ui/src/app/ng2/services/http.service.ts +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * ============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========================================================= - */ - -import {Injectable, Inject} from '@angular/core'; -import {Http, XHRBackend, RequestOptions, Request, RequestOptionsArgs, Response, Headers} from '@angular/http'; -import {Observable} from 'rxjs/Observable'; -import {UUID} from 'angular2-uuid'; -import 'rxjs/add/operator/map'; -import 'rxjs/add/operator/catch'; -import 'rxjs/add/observable/throw'; -import {Dictionary} from "../../utils/dictionary/dictionary"; -import {SharingService, CookieService} from "app/services"; -import { ModalService } from "app/ng2/services/modal.service"; -import { ServerErrorResponse } from "app/models"; -import {ErrorMessageComponent} from "../components/ui/modal/error-message/error-message.component"; -import {SdcConfigToken, ISdcConfig} from "../config/sdc-config.config"; - -@Injectable() -export class HttpService extends Http { - - constructor(backend: XHRBackend, options: RequestOptions, private sharingService: SharingService, private cookieService: CookieService, private modalService: ModalService, @Inject(SdcConfigToken) private sdcConfig:ISdcConfig) { - super(backend, options); - this._defaultOptions.withCredentials = true; - this._defaultOptions.headers.append(cookieService.getUserIdSuffix(), cookieService.getUserId()); - } - - request(request:string|Request, options?:RequestOptionsArgs):Observable { - /** - * For every request to the server, that the service id, or resource id is sent in the URL, need to pass UUID in the header. - * Check if the unique id exists in uuidMap, and if so get the UUID and add it to the header. - */ - if (typeof request === 'string') { // meaning we have to add the token to the options, not in url - if (!options) { - // make option object - options = {headers: new Headers()}; - } - - var uuidValue = this.getUuidValue(request); - if(uuidValue!= ''){ - options.headers['X-ECOMP-ServiceID'] = uuidValue; - - } - options.headers.set('X-ECOMP-RequestID', UUID.UUID()); - - } else { - // we have to add the token to the url object - var uuidValue = this.getUuidValue((request).url); - if(uuidValue!= ''){ - request.headers.set('X-ECOMP-ServiceID',uuidValue); - - } - request.headers.set('X-ECOMP-RequestID', UUID.UUID()); - } - return super.request(request, options).catch((err) => this.catchError(err)); - } - - private getUuidValue = (url: string) :string => { - let map:Dictionary = this.sharingService.getUuidMap(); - if (map && url.indexOf(this.sdcConfig.api.root) > 0) { - map.forEach((key:string) => { - if (url.indexOf(key) !== -1) { - return this.sharingService.getUuidValue(key); - } - }); - } - return ''; - } - - private catchError = (response: Response): Observable => { - - let modalInstance = this.modalService.createErrorModal("OK"); - let errorResponse: ServerErrorResponse = new ServerErrorResponse(response); - this.modalService.addDynamicContentToModal(modalInstance, ErrorMessageComponent, errorResponse); - modalInstance.instance.open(); - - return Observable.throw(response); - }; - - public static replaceUrlParams(url:string, urlParams:{[index:string]:any}):string { - return url.replace(/:(\w+)/g, (m, p1):string => urlParams[p1] || ''); - } - -} diff --git a/catalog-ui/src/app/ng2/services/modules.service.ts b/catalog-ui/src/app/ng2/services/modules.service.ts new file mode 100644 index 0000000000..857f0718d6 --- /dev/null +++ b/catalog-ui/src/app/ng2/services/modules.service.ts @@ -0,0 +1,34 @@ +import {Inject, Injectable} from "@angular/core"; +import {HttpClient} from "@angular/common/http"; +import {ISdcConfig, SdcConfigToken} from "../config/sdc-config.config"; +import {DisplayModule, Module} from "../../models/modules/base-module"; +import {Observable} from "rxjs/Observable"; +import {ServerTypeUrl} from "../../utils/constants"; + +@Injectable() +export class ModulesService { + + protected baseUrl; + + constructor(private http: HttpClient, @Inject(SdcConfigToken) sdcConfig: ISdcConfig) { + this.baseUrl = sdcConfig.api.root + sdcConfig.api.component_api_root; + } + + getComponentInstanceModule = (topologyTemplateType: string, topologyTemplateId: string, componentInstanceId: string, moduleId: string):Observable => { + return this.http.get(this.baseUrl + ServerTypeUrl.toServerTypeUrl(topologyTemplateType) + "/" + topologyTemplateId + "/resourceInstance/" + componentInstanceId + "/groupInstance/" + moduleId) + .map((response) => { + return new DisplayModule(response); + }) + }; + + getModuleForDisplay = (topologyTemplateType: string, topologyTemplateId: string, moduleId: string):Observable => { + return this.http.get(this.baseUrl + ServerTypeUrl.toServerTypeUrl(topologyTemplateType) + "/" + topologyTemplateId + "/groups/" + moduleId) + .map((response) => { + return new DisplayModule(response); + }) + }; + + public updateModuleMetadata = (topologyTemplateType: string, topologyTemplateId: string, module: Module):Observable => { + return this.http.put(this.baseUrl + ServerTypeUrl.toServerTypeUrl(topologyTemplateType) + "/" + topologyTemplateId + "/groups/" + module.uniqueId + "/metadata", module) + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/services/onboarding.service.ts b/catalog-ui/src/app/ng2/services/onboarding.service.ts new file mode 100644 index 0000000000..0ec4875d91 --- /dev/null +++ b/catalog-ui/src/app/ng2/services/onboarding.service.ts @@ -0,0 +1,151 @@ +/** + * Created by rc2122 on 6/4/2018. + */ +/*- + * ============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========================================================= + */ + +'use strict'; +import {Inject, Injectable} from "@angular/core"; +import {SdcConfigToken, ISdcConfig} from "app/ng2/config/sdc-config.config"; +import {Observable} from "rxjs/Observable"; +import { HttpClient, HttpResponse } from "@angular/common/http"; +import { ComponentFactory } from "../../utils/component-factory"; +import { DEFAULT_ICON, ComponentType } from "../../utils/constants"; +import { ICsarComponent } from "../../models/csar-component"; +import { IApi } from "../../models/app-config"; +import { CacheService } from "./cache.service"; +import { IComponentMetadata, ComponentMetadata } from "../../models/component-metadata"; +import { IMainCategory, ISubCategory } from "../../models/category"; +import { Resource } from "../../models/components/resource"; + +export interface OnboardingComponents { + listCount: number; + results: Array +} + +@Injectable() +export class OnboardingService { + private api:IApi; + + constructor(protected http: HttpClient, + private cacheService:CacheService, + @Inject(SdcConfigToken) sdcConfig:ISdcConfig, + private componentFactory: ComponentFactory) { + this.api = sdcConfig.api; + } + + getOnboardingVSPs = (): Observable> =>{ + return this.http.get(this.api.GET_onboarding).map((onboardingVSPs) =>{ + return onboardingVSPs.results + }); + } + + getOnboardingComponents = ():Observable> => { + return this.getOnboardingVSPs().map((onboardingComponents) => { + let componentsMetadataList: Array = new Array(); + onboardingComponents.forEach((obc:ICsarComponent) => { + let componentMetaData: ComponentMetadata = this.createFromCsarComponent(obc); + componentsMetadataList.push(componentMetaData); + }); + return componentsMetadataList; + }); + }; + + public createFromCsarComponent = (csar:ICsarComponent): ComponentMetadata => { + let newMetadata = new ComponentMetadata(); + newMetadata.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:IMainCategory)=> { + if (main.subcategories) { + allSubs = allSubs.concat(main.subcategories); + } + }); + + let selectedCategory:IMainCategory = _.find(availableCategories, function (main:IMainCategory) { + return main.uniqueId === csar.category; + }); + + let selectedSubCategory:ISubCategory = _.find(allSubs, (sub:ISubCategory)=> { + return sub.uniqueId === csar.subCategory; + }); + + // Build the categories and sub categories array (same format as component category) + let categories:Array = new Array(); + let subcategories:Array = new Array(); + if (selectedCategory && selectedSubCategory) { + subcategories.push(selectedSubCategory); + selectedCategory.subcategories = subcategories; + categories.push(selectedCategory); + } + + // Fill the component with details from CSAR + + newMetadata.categories = categories; + newMetadata.vendorName = csar.vendorName; + newMetadata.vendorRelease = csar.vendorRelease; + newMetadata.csarUUID = csar.packageId; + newMetadata.csarPackageType = csar.packageType; + newMetadata.csarVersion = csar.version; + newMetadata.packageId = csar.packageId; + newMetadata.description = csar.description; + newMetadata.selectedCategory = selectedCategory && selectedSubCategory ? selectedCategory.name + "_#_" + selectedSubCategory.name : ''; + newMetadata.filterTerm = newMetadata.name + ' ' + newMetadata.description + ' ' + newMetadata.vendorName + ' ' + newMetadata.csarVersion; + newMetadata.resourceType = "VF"; + newMetadata.componentType = ComponentType.RESOURCE; + newMetadata.tags = []; + newMetadata.icon = DEFAULT_ICON; + newMetadata.iconSprite = "sprite-resource-icons"; + return newMetadata; + }; + + downloadOnboardingCsar = (packageId:string):Observable> => { + return this.http.get(this.api.GET_onboarding + "/" + packageId, {observe: 'response', responseType: 'blob'}); + }; + + getComponentFromCsarUuid = (csarUuid:string):Observable => { + return this.http.get(this.api.root + this.api.GET_component_from_csar_uuid.replace(':csar_uuid', csarUuid)) + .map((response: any) => { + // If the status is 400, this means that the component not found. + // I do not want to return error from server, because a popup will appear in client with the error. + // So returning success (200) with status 400. + if (response.status !== 400) { + let componentMetadata = new ComponentMetadata(); + componentMetadata = response; + return componentMetadata; + } + }); + }; + + //TODO remove when workspace page convert to angular5 + convertMetaDataToComponent(componentMetadata: ComponentMetadata) { + let newResource: Resource = this.componentFactory.createEmptyComponent(ComponentType.RESOURCE); + newResource.setComponentMetadata(componentMetadata); + return newResource; + } +} diff --git a/catalog-ui/src/app/ng2/services/plugins.service.ts b/catalog-ui/src/app/ng2/services/plugins.service.ts index 2a3b68fe25..0f71eee1f0 100644 --- a/catalog-ui/src/app/ng2/services/plugins.service.ts +++ b/catalog-ui/src/app/ng2/services/plugins.service.ts @@ -1,40 +1,40 @@ -import { Injectable, Inject } from '@angular/core'; +import {Inject, Injectable} from '@angular/core'; import {Observable} from 'rxjs/Observable'; import {Http, Response} from '@angular/http'; -import {IApi, IAppConfigurtaion, Plugin, Plugins, PluginsConfiguration} from "app/models"; +import {IApi, IAppConfigurtaion, Plugin, PluginsConfiguration} from "app/models"; import {ISdcConfig, SdcConfigToken} from "../config/sdc-config.config"; @Injectable() export class PluginsService { - private baseUrl; public configuration: IAppConfigurtaion; public api: IApi; + private baseUrl; - constructor(private http: Http, @Inject(SdcConfigToken) private sdcConfig:ISdcConfig) { + constructor(private http: Http, @Inject(SdcConfigToken) private sdcConfig: ISdcConfig) { this.api = this.sdcConfig.api; this.baseUrl = this.api.root + this.sdcConfig.api.component_api_root; } public getPluginByStateUrl = (stateUrl: string) => { - let pluginKey: any = _.findKey(PluginsConfiguration.plugins, (pluginConfig: Plugin) =>{ - return pluginConfig.pluginStateUrl === stateUrl; + let pluginKey: any = _.findKey(PluginsConfiguration.plugins, (pluginConfig: Plugin) => { + return pluginConfig.pluginStateUrl === stateUrl; }); return PluginsConfiguration.plugins[pluginKey]; }; - public isPluginDisplayedInContext = (plugin: Plugin ,userRole: string, contextType: string) => { + public isPluginDisplayedInContext = (plugin: Plugin, userRole: string, contextType: string) => { return plugin.pluginDisplayOptions["context"] && - plugin.pluginDisplayOptions["context"].displayRoles.includes(userRole) && - plugin.pluginDisplayOptions["context"].displayContext.indexOf(contextType) !== -1 + plugin.pluginDisplayOptions["context"].displayRoles.includes(userRole) && + plugin.pluginDisplayOptions["context"].displayContext.indexOf(contextType) !== -1 }; public isPluginOnline = (pluginId: string): Observable => { - let url:string = this.api.no_proxy_root + this.api.GET_plugin_online_state.replace(':pluginId', pluginId); + let url: string = this.api.no_proxy_root + this.api.GET_plugin_online_state.replace(':pluginId', pluginId); return this.http.get(url).map((res: Response) => { return res.json() }) - .catch(error => Observable.of(false)); + .catch(error => Observable.of(false)); } } diff --git a/catalog-ui/src/app/ng2/services/policies.service.ts b/catalog-ui/src/app/ng2/services/policies.service.ts index 3675a7b9ab..a1a9013303 100644 --- a/catalog-ui/src/app/ng2/services/policies.service.ts +++ b/catalog-ui/src/app/ng2/services/policies.service.ts @@ -20,13 +20,13 @@ import {Injectable, Inject} from "@angular/core"; import {Observable} from "rxjs/Observable"; -import {HttpService} from "./http.service"; import {SdcConfigToken, ISdcConfig} from "../config/sdc-config.config"; import {PolicyInstance, PolicyTargetsRequest} from '../../models/graph/zones/policy-instance'; import {IZoneInstanceAssignment} from "../../models/graph/zones/zone-instance"; import {IZoneService} from "../../models/graph/zones/zone"; import {TargetUiObject} from "../../models/ui-models/ui-target-object"; import {TargetOrMemberType} from "../../utils/constants"; +import { HttpClient } from "@angular/common/http"; @Injectable() @@ -38,14 +38,12 @@ export class PoliciesService implements IZoneService { 'SERVICE': 'services' } - constructor(private http:HttpService, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) { + constructor(private http: HttpClient, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) { this.baseUrl = sdcConfig.api.root; } - public createPolicyInstance(topologyTemplateType:string, topologyTemplateId:string, policyType:string) { - return this.http.post(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyType, {}).map(resp => { - return resp.json(); - }); + public createPolicyInstance(topologyTemplateType:string, topologyTemplateId:string, policyType:string): Observable { + return this.http.post(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyType, {}); } public addPolicyTarget(topologyTemplateType:string, topologyTemplateId:string, policy:PolicyInstance, targetId:string, targetType:TargetOrMemberType) { @@ -76,8 +74,8 @@ export class PoliciesService implements IZoneService { } public updatePolicyTargets(topologyTemplateType:string, topologyTemplateId:string, policyId:string, targets:PolicyTargetsRequest): Observable { - return this.http.post(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyId + '/targets', targets.requestItems) - .map(response => new PolicyInstance(response.json())); + return this.http.post(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyId + '/targets', targets.requestItems) + .map(response => new PolicyInstance(response)); } public updateTargets(topologyTemplateType:string, topologyTemplateId:string, policyId:string, targets:Array):Observable { @@ -94,22 +92,18 @@ export class PoliciesService implements IZoneService { } public getSpecificPolicy(topologyTemplateType:string, topologyTemplateId:string, policyId:string):Observable { - return this.http.get(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyId) + return this.http.get(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyId) .map(res => { - return new PolicyInstance(res.json()); + return new PolicyInstance(res); }); } public updateName(topologyTemplateType:string, topologyTemplateId:string, policyId:string, newName:string):Observable { - return this.http.put(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyId, {name: newName}).map(res => { - return res.json(); - }); + return this.http.put(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyId, {name: newName}); }; public deletePolicy(topologyTemplateType:string, topologyTemplateId:string, policyId:string) { - return this.http.delete(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyId).map(resp => { - return resp.json(); - }); + return this.http.delete(this.baseUrl + '/v1/catalog/' + this.mapApiDirections[topologyTemplateType.toUpperCase()] + '/' + topologyTemplateId + '/policies/' + policyId); }; public updateZoneInstanceAssignments(topologyTemplateType:string, topologyTemplateId:string, policyId:string, targets:Array):Observable{ diff --git a/catalog-ui/src/app/ng2/services/responses/component-generic-response.ts b/catalog-ui/src/app/ng2/services/responses/component-generic-response.ts index d297ea0874..f161babfa6 100644 --- a/catalog-ui/src/app/ng2/services/responses/component-generic-response.ts +++ b/catalog-ui/src/app/ng2/services/responses/component-generic-response.ts @@ -22,12 +22,15 @@ * Created by ob0695 on 4/18/2017. */ -import { ArtifactGroupModel, PropertyModel, PropertiesGroup, InputsGroup, AttributeModel, AttributesGroup, ComponentInstance, OperationModel, - InputBEModel, Module, ComponentMetadata, RelationshipModel, RequirementsGroup, CapabilitiesGroup, InterfaceModel} from "app/models"; +import { ArtifactGroupModel, PropertyModel, PropertiesGroup, AttributeModel, AttributesGroup, ComponentInstance, OperationModel, + InputBEModel, Module, ComponentMetadata, RelationshipModel, RequirementsGroup, CapabilitiesGroup} from "app/models"; import {CommonUtils} from "app/utils"; import {Serializable} from "../utils/serializable"; +import {PropertyBEModel} from "../../../models/properties-inputs/property-be-model"; import { PolicyInstance } from "app/models/graph/zones/policy-instance"; import { GroupInstance } from "../../../models/graph/zones/group-instance"; +import { InputsGroup } from "../../../models/inputs"; +import { InterfaceModel } from "../../../models/operation"; export class ComponentGenericResponse implements Serializable { @@ -40,7 +43,7 @@ export class ComponentGenericResponse implements Serializable; public componentInstances:Array; - public componentInstancesInterfaces:Map>; + public componentInstancesInterfaces: Map>; public inputs:Array; public capabilities:CapabilitiesGroup; public requirements:RequirementsGroup; @@ -75,7 +78,7 @@ export class ComponentGenericResponse implements Serializable { public forwardingPaths: { [key:string]:ForwardingPath } = {}; + public serviceApiArtifacts: ArtifactGroupModel; deserialize (response): ServiceGenericResponse { super.deserialize(response); + this.serviceApiArtifacts = new ArtifactGroupModel(response.serviceApiArtifacts); if(response.forwardingPaths) { _.forEach(response.forwardingPaths, (pathResponse, id) => { let pathId = id; diff --git a/catalog-ui/src/app/ng2/services/sharing.service.ts b/catalog-ui/src/app/ng2/services/sharing.service.ts new file mode 100644 index 0000000000..0a6b8cb1af --- /dev/null +++ b/catalog-ui/src/app/ng2/services/sharing.service.ts @@ -0,0 +1,42 @@ +/*- + * ============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========================================================= + */ + +import {Injectable} from "@angular/core"; +import {Dictionary} from "app/utils"; + +@Injectable() +export class SharingService { + private uuidMap:Dictionary = new Dictionary(); + + constructor() { + } + + public getUuidValue(uniqueId:string): string { + return this.uuidMap.getValue(uniqueId); + } + + public addUuidValue(uniqueId:string, uuid:string): void { + this.uuidMap.setValue(uniqueId, uuid); + } + + public getUuidMap() :Dictionary { + return this.uuidMap; + } +} diff --git a/catalog-ui/src/app/ng2/services/tosca-types.service.ts b/catalog-ui/src/app/ng2/services/tosca-types.service.ts index 66826c0fef..83b833b1ab 100644 --- a/catalog-ui/src/app/ng2/services/tosca-types.service.ts +++ b/catalog-ui/src/app/ng2/services/tosca-types.service.ts @@ -14,12 +14,19 @@ * permissions and limitations under the License. */ -import {Injectable, Inject} from '@angular/core'; -import {Observable} from 'rxjs/Observable'; -import {HttpService} from './http.service'; -import {SdcConfigToken, ISdcConfig} from "../config/sdc-config.config"; -import {CapabilityTypesMap, NodeTypesMap, RelationshipTypesMap} from "app/models"; -import {Response} from '@angular/http'; +import { HttpClient } from '@angular/common/http'; +import { Inject, Injectable } from '@angular/core'; +import { Response } from '@angular/http'; +import { + CapabilityTypeModel, + CapabilityTypesMap, + IComponentsArray, + NodeTypesMap, + RelationshipTypesMap +} from 'app/models'; +import { Observable } from 'rxjs/Observable'; +import { ISdcConfig, SdcConfigToken } from '../config/sdc-config.config'; +import 'rxjs/add/operator/toPromise'; declare var angular: angular.IAngularStatic; @@ -28,28 +35,20 @@ export class ToscaTypesServiceNg2 { protected baseUrl; - constructor(protected http: HttpService, @Inject(SdcConfigToken) sdcConfig: ISdcConfig) { + constructor(protected http: HttpClient, @Inject(SdcConfigToken) sdcConfig: ISdcConfig) { this.baseUrl = sdcConfig.api.root + sdcConfig.api.component_api_root; } - fetchRelationshipTypes(): Observable { - return this.http.get(this.baseUrl + 'relationshipTypes') - .map((res: Response) => { - return res.json(); - }); + async fetchRelationshipTypes(): Promise { + return this.http.get(this.baseUrl + 'relationshipTypes').toPromise(); } - fetchNodeTypes(): Observable { - return this.http.get(this.baseUrl + 'nodeTypes') - .map((res: Response) => { - return res.json(); - }); + async fetchNodeTypes(): Promise { + return this.http.get(this.baseUrl + 'nodeTypes').toPromise(); } - fetchCapabilityTypes(): Observable { - return this.http.get(this.baseUrl + 'capabilityTypes') - .map((res: Response) => { - return res.json(); - }); + async fetchCapabilityTypes(): Promise{ + return this.http.get(this.baseUrl + 'capabilityTypes').toPromise(); } } + diff --git a/catalog-ui/src/app/ng2/services/user.service.ts b/catalog-ui/src/app/ng2/services/user.service.ts index 87e90432dc..f4186a1087 100644 --- a/catalog-ui/src/app/ng2/services/user.service.ts +++ b/catalog-ui/src/app/ng2/services/user.service.ts @@ -19,80 +19,34 @@ */ import { Injectable, Inject } from "@angular/core"; -import { Headers } from "@angular/http"; import { Observable } from "rxjs/Observable"; -import { HttpService } from "./http.service"; -import { Cookie2Service } from "./cookie.service"; import { IUserProperties } from "../../models/user"; -import {ICookie} from "../../models/app-config"; import {SdcConfigToken, ISdcConfig} from "../config/sdc-config.config"; - +import { HttpClient } from "@angular/common/http"; +import { HttpHelperService } from "./http-hepler.service"; +/** + * User Service provides CRUD for Users. See authentication service for authentication/login. + */ @Injectable() -export class UserService { +export class UserService { private url:string; - private authorizeUrl:string; - private _loggedinUser:IUserProperties; - - constructor(private httpService:HttpService, - private cookieService:Cookie2Service, + constructor(private http: HttpClient, @Inject(SdcConfigToken) private sdcConfig:ISdcConfig) { this.url = this.sdcConfig.api.root + this.sdcConfig.api.GET_user; - this.authorizeUrl = this.sdcConfig.api.root + this.sdcConfig.api.GET_user_authorize; } - public authorize() :Observable { - let cookie:ICookie = this.sdcConfig.cookie; - let authorizeHeaders:Headers = new Headers(); - authorizeHeaders.set(cookie.userFirstName, this.cookieService.getFirstName()); - authorizeHeaders.set(cookie.userLastName, this.cookieService.getLastName()); - authorizeHeaders.set(cookie.userEmail, this.cookieService.getEmail()); - authorizeHeaders.set(cookie.userIdSuffix, this.cookieService.getUserId()); - - return this.httpService.get( - this.authorizeUrl, - { headers: authorizeHeaders } - ).map(resp => resp.json()); - } public getAllUsers() :Observable { - return this.httpService.get( + return this.http.get( this.sdcConfig.api.root + this.sdcConfig.api.GET_all_users - ).map(resp => resp.json()); + ).map(resp => resp) ; } public getUser(userId:string) :Observable { - return this.httpService.get( - HttpService.replaceUrlParams(this.url, { id: userId }) - ).map(resp => resp.json()); - } - - public createUser(userData:{[index:string]: any}) :Observable { - return this.httpService.post( - this.sdcConfig.api.root + this.sdcConfig.api.POST_create_user, - userData - ).map(resp => resp.json()); + return this.http.get( + HttpHelperService.replaceUrlParams(this.url, { id: userId }) + ).map(resp => resp); } - - public deleteUser(userId:string) :Observable { - return this.httpService.delete( - HttpService.replaceUrlParams(this.sdcConfig.api.root + this.sdcConfig.api.DELETE_delete_user, { id: userId }) - ).map(resp => resp.json()); - } - - public editUserRole(userId:string, role:string) :Observable { - return this.httpService.post( - HttpService.replaceUrlParams(this.sdcConfig.api.root + this.sdcConfig.api.POST_edit_user_role, { id: userId }), - { role: role } - ).map(resp => resp.json()); - } - - public getLoggedinUser():IUserProperties { - return this._loggedinUser; - } - - public setLoggedinUser(loggedinUser:IUserProperties) { - this._loggedinUser = loggedinUser; - }; } diff --git a/catalog-ui/src/app/ng2/services/workflow.service.ts b/catalog-ui/src/app/ng2/services/workflow.service.ts index 81a2ea3b7f..044ca37266 100644 --- a/catalog-ui/src/app/ng2/services/workflow.service.ts +++ b/catalog-ui/src/app/ng2/services/workflow.service.ts @@ -1,14 +1,13 @@ import { Injectable, Inject } from "@angular/core"; -import { Response } from "@angular/http"; import { Observable } from "rxjs/Observable"; -import { HttpService } from "./http.service"; import { SdcConfigToken, ISdcConfig } from "../config/sdc-config.config"; +import { HttpClient } from "@angular/common/http"; import { Component, OperationModel } from "app/models"; interface WorkflowOutputParameter { - name: string, - type: string, - mandatory: boolean + name: string; + type: string; + mandatory: boolean; } interface WorkflowInputParameter extends WorkflowOutputParameter { @@ -25,40 +24,31 @@ export class WorkflowServiceNg2 { WF_STATE_ARCHIVED = 'ARCHIVED'; VERSION_STATE_CERTIFIED = 'CERTIFIED'; - constructor(private http: HttpService, @Inject(SdcConfigToken) sdcConfig: ISdcConfig) { + constructor(private http: HttpClient, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) { this.baseUrl = sdcConfig.api.workflow_root; this.catalogBaseUrl = sdcConfig.api.POST_workflow_artifact; } public associateWorkflowArtifact(component: Component, operation: OperationModel): Observable { - return this.http.post(this.baseUrl + '/workflows/' + operation.workflowId + '/versions/' + operation.workflowVersionId + '/artifact-deliveries', { - endpoint: this.catalogBaseUrl + '/' + component.getTypeUrl() + component.uuid + '/interfaces/' + operation.interfaceId + '/operations/' + operation.uniqueId + '/artifacts/' + operation.implementation.artifactUUID, - method: 'POST' - }) - .map((res:Response) => { - return res.json(); + return this.http.post(this.baseUrl + '/workflows/' + operation.workflowId + '/versions/' + operation.workflowVersionId + '/artifact-deliveries', { + endpoint: this.catalogBaseUrl + '/' + component.getTypeUrl() + component.uuid + '/interfaces/' + operation.interfaceId + '/operations/' + + operation.uniqueId + '/artifacts/' + operation.implementation.artifactUUID, method: 'POST' }); } public getWorkflows(filterCertified: boolean = true): Observable { - return this.http.get(this.baseUrl + '/workflows' + (filterCertified ? '?versionState=' + this.VERSION_STATE_CERTIFIED : '')) - .map((res:Response) => { - return res.json().items; - }); + return this.http.get(this.baseUrl + '/workflows' + (filterCertified ? '?versionState=' + this.VERSION_STATE_CERTIFIED : '')); } public getWorkflowVersions(workflowId: string, filterCertified: boolean = true): Observable { - return this.http.get(this.baseUrl + '/workflows/' + workflowId + '/versions' + (filterCertified ? '?state=' + this.VERSION_STATE_CERTIFIED : '')) - .map((res:Response) => { - return _.map(res.json().items, version => version); + return this.http.get(this.baseUrl + '/workflows/' + workflowId + '/versions' + (filterCertified ? '?state=' + this.VERSION_STATE_CERTIFIED : '')) + .map((res) => { + return res.items; }); } public updateWorkflowVersion(workflowId: string, versionId: string, payload: any): Observable { - return this.http.put(this.baseUrl + '/workflows/' + workflowId + '/versions/' + versionId, payload) - .map((res:Response) => { - return res.json(); - }); + return this.http.put(this.baseUrl + '/workflows/' + workflowId + '/versions/' + versionId, payload); } } diff --git a/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.html b/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.html index bee493f2ae..7b9a5ff700 100644 --- a/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.html +++ b/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.html @@ -13,7 +13,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -
diff --git a/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.ts b/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.ts index 68cfedb32b..4cff9de72a 100644 --- a/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.ts +++ b/catalog-ui/src/app/ng2/shared/multiline-ellipsis/multiline-ellipsis.component.ts @@ -1,4 +1,4 @@ -import {Component, OnChanges, AfterViewChecked, ViewChild, ElementRef, Input, Output, SimpleChanges, EventEmitter} from "@angular/core"; +import {Component, OnChanges, AfterContentInit, ViewChild, ElementRef, Input, Output, SimpleChanges, EventEmitter} from "@angular/core"; import {WindowRef} from "../../services/window.service"; @Component({ @@ -6,7 +6,7 @@ import {WindowRef} from "../../services/window.service"; templateUrl: 'multiline-ellipsis.component.html', styleUrls: ['multiline-ellipsis.component.less'] }) -export class MultilineEllipsisComponent implements OnChanges, AfterViewChecked { +export class MultilineEllipsisComponent implements OnChanges, AfterContentInit { @Input() public lines: number; @Input() public lineHeight: string; @@ -30,7 +30,7 @@ export class MultilineEllipsisComponent implements OnChanges, AfterViewChecked { this.prepareStyles() } - public ngAfterViewChecked() { + public ngAfterContentInit() { const hasEllipsis = (this.elmContainer.nativeElement.offsetHeight < this.elmContent.nativeElement.offsetHeight); if (hasEllipsis !== this.hasEllipsis) { this.hasEllipsis = hasEllipsis; diff --git a/catalog-ui/src/app/ng2/shared/translator/translate.pipe.ts b/catalog-ui/src/app/ng2/shared/translator/translate.pipe.ts index 4ec756bcc2..04f6650f38 100644 --- a/catalog-ui/src/app/ng2/shared/translator/translate.pipe.ts +++ b/catalog-ui/src/app/ng2/shared/translator/translate.pipe.ts @@ -19,38 +19,32 @@ */ import { Pipe, PipeTransform } from '@angular/core'; -import { TranslateService, ITranslateArgs } from "./translate.service"; +import { ITranslateArgs, TranslateService } from './translate.service'; +// tslint:disable-next-line:interface-name +interface ITranslateParams { + phrase: string; + args: ITranslateArgs; + language: string; +} @Pipe({ name: 'translate', pure: false }) export class TranslatePipe implements PipeTransform { - private translated:string; - private lastParams: { - phrase: string; - args: {[index: string]: any}; - language: string; - } = { + private translated: string; + private lastParams: ITranslateParams = { phrase: undefined, args: undefined, language: undefined }; - constructor(private translateService:TranslateService) { - } - - private shouldUpdate(curParams:{[index:string]: any}) : boolean { - return ( - curParams.language !== this.lastParams.language || - curParams.args !== this.lastParams.args || - curParams.phrase !== this.lastParams.phrase - ); + constructor(private translateService: TranslateService) { } - public transform(phrase:string, args:ITranslateArgs, language:string=this.translateService.activeLanguage) : string { - const curParams = { phrase, args, language }; + public transform(phrase: string, args: ITranslateArgs, language: string = this.translateService.activeLanguage): string { + const curParams: ITranslateParams = { phrase, args, language }; if (this.shouldUpdate(curParams)) { this.lastParams = curParams; this.translated = this.translateService.translate(phrase, args, language); @@ -58,4 +52,12 @@ export class TranslatePipe implements PipeTransform { return this.translated; } + + private shouldUpdate(curParams: ITranslateParams): boolean { + return ( + curParams.language !== this.lastParams.language || + curParams.args !== this.lastParams.args || + curParams.phrase !== this.lastParams.phrase + ); + } } diff --git a/catalog-ui/src/app/ng2/shared/translator/translate.service.config.ts b/catalog-ui/src/app/ng2/shared/translator/translate.service.config.ts index a1d7833062..6413f6a64e 100644 --- a/catalog-ui/src/app/ng2/shared/translator/translate.service.config.ts +++ b/catalog-ui/src/app/ng2/shared/translator/translate.service.config.ts @@ -18,9 +18,9 @@ * ============LICENSE_END========================================================= */ -import { OpaqueToken } from "@angular/core"; +import { InjectionToken } from "@angular/core"; -export const TranslateServiceConfigToken = new OpaqueToken('TranslateServiceConfigToken'); +export const TranslateServiceConfigToken = new InjectionToken('TranslateServiceConfigToken'); export interface ITranslateServiceConfig { filePrefix:string; diff --git a/catalog-ui/src/app/ng2/shared/translator/translate.service.ts b/catalog-ui/src/app/ng2/shared/translator/translate.service.ts index ff7c643b46..0b5ddae557 100644 --- a/catalog-ui/src/app/ng2/shared/translator/translate.service.ts +++ b/catalog-ui/src/app/ng2/shared/translator/translate.service.ts @@ -19,9 +19,9 @@ */ import { Injectable, Inject } from "@angular/core"; -import { Response, Http } from "@angular/http"; -import { Observable, Observer, ConnectableObservable, Subscription } from "rxjs"; import { ITranslateServiceConfig, TranslateServiceConfigToken } from "./translate.service.config"; +import { Observer, Subscription, Observable, ConnectableObservable } from 'rxjs/Rx'; +import { HttpClient } from "@angular/common/http"; export { ITranslateServiceConfig, TranslateServiceConfigToken }; @@ -145,7 +145,7 @@ export class TranslateService { private _cacheLanguagesJsons:{[index:string]:ITranslateLanguageJson} = {}; private _cacheLanguagesLoaders:{[index:string]:Observable} = {}; - constructor(@Inject(TranslateServiceConfigToken) private config:ITranslateServiceConfig, private http:Http) { + constructor(@Inject(TranslateServiceConfigToken) private config:ITranslateServiceConfig, private http: HttpClient) { this.initLanguageObservable(); this.loadAndActivateLanguage(this.config.defaultLanguage); } @@ -176,8 +176,7 @@ export class TranslateService { if (!(language in this._cacheLanguagesLoaders)) { const filePath = `${this.config.filePrefix}${language}${this.config.fileSuffix}`; - this._cacheLanguagesLoaders[language] = this.http.get(filePath) - .map(resp => resp.json()) + this._cacheLanguagesLoaders[language] = this.http.get(filePath) .catch(() => Observable.throw(`Failed to load language file for "${language}"`)) .publish(); (>this._cacheLanguagesLoaders[language]).connect(); @@ -204,12 +203,12 @@ export class TranslateService { return false; } - public loadAndActivateLanguage(language:string) : Observable { + public loadAndActivateLanguage(language:string) : void { + const loadLanguageObservable = this.loadLanguageJsonFile(language, false); loadLanguageObservable.subscribe(() => { this.activateLanguage(language); }, () => {}); - return loadLanguageObservable; } public translate(phraseKey:string, args:ITranslateArgs={}, language:string=this._activeLanguage) : string { diff --git a/catalog-ui/src/app/ng2/store/actions/artifacts.action.ts b/catalog-ui/src/app/ng2/store/actions/artifacts.action.ts new file mode 100644 index 0000000000..a00cc3a9ec --- /dev/null +++ b/catalog-ui/src/app/ng2/store/actions/artifacts.action.ts @@ -0,0 +1,25 @@ +/** + * Created by ob0695 + */ +import {ArtifactModel} from "../../../models/artifacts"; + +export class GetArtifactsByTypeAction { + static readonly type = '[ARTIFACTS] GetArtifactsByType'; + + constructor(public payload: {componentType:string, componentId:string, artifactType: string}) { + } +} + +export class CreateOrUpdateArtifactAction { + static readonly type = '[ARTIFACTS] CreateOrUpdateArtifactAction'; + + constructor(public payload: {componentType:string, componentId:string, artifact:ArtifactModel}) { + } +} + +export class DeleteArtifactAction { + static readonly type = '[ARTIFACTS] DeleteArtifactAction'; + + constructor(public payload: {componentType:string, componentId:string, artifact: ArtifactModel}) { + } +} diff --git a/catalog-ui/src/app/ng2/store/actions/instance-artifacts.actions.ts b/catalog-ui/src/app/ng2/store/actions/instance-artifacts.actions.ts new file mode 100644 index 0000000000..0f1df78352 --- /dev/null +++ b/catalog-ui/src/app/ng2/store/actions/instance-artifacts.actions.ts @@ -0,0 +1,32 @@ +/** + * Created by ob0695 + */ +import {ArtifactModel} from "../../../models/artifacts"; + +export class GetInstanceArtifactsByTypeAction { + static readonly type = '[INSTANCE_ARTIFACTS] GetInstanceArtifactsByTypeAction'; + + constructor(public payload: { componentType: string, componentId: string, artifactType: string, instanceId: string }) { + } +} + +export class CreateInstanceArtifactAction { + static readonly type = '[INSTANCE_ARTIFACTS] CreateInstanceArtifactAction'; + + constructor(public payload: { componentType: string, componentId: string, instanceId: string, artifact: ArtifactModel }) { + } +} + +export class UpdateInstanceArtifactAction { + static readonly type = '[INSTANCE_ARTIFACTS] UpdateInstanceArtifactAction'; + + constructor(public payload: { componentType: string, componentId: string, instanceId: string, artifact: ArtifactModel }) { + } +} + +export class DeleteInstanceArtifactAction { + static readonly type = '[INSTANCE_ARTIFACTS] DeleteInstanceArtifactAction'; + + constructor(public payload: { componentType: string, componentId: string, instanceId: string, artifact: ArtifactModel }) { + } +} diff --git a/catalog-ui/src/app/ng2/store/actions/workspace.action.ts b/catalog-ui/src/app/ng2/store/actions/workspace.action.ts new file mode 100644 index 0000000000..c7f18e0ac6 --- /dev/null +++ b/catalog-ui/src/app/ng2/store/actions/workspace.action.ts @@ -0,0 +1,17 @@ +/** + * Created by ob0695 on 7/17/2018. + */ + +export class UpdateIsViewOnly { + static readonly type = '[WORKSPACE] UpdateIsViewOnly'; + + constructor(public isViewOnly:boolean) { + } +} + +export class UpdateIsDesigner { + static readonly type = '[WORKSPACE] UpdateIsDesigner'; + + constructor(public isDesigner:boolean) { + } +} diff --git a/catalog-ui/src/app/ng2/store/states/artifacts.state.spec.ts b/catalog-ui/src/app/ng2/store/states/artifacts.state.spec.ts new file mode 100644 index 0000000000..c59a4455b6 --- /dev/null +++ b/catalog-ui/src/app/ng2/store/states/artifacts.state.spec.ts @@ -0,0 +1,62 @@ +import { Store } from '@ngxs/store'; +import { Observable } from 'rxjs/Rx'; +import { Mock } from 'ts-mockery'; +import { ArtifactModel } from '../../../models/artifacts'; +import { ArtifactGroupType } from '../../../utils/constants'; +import { ComponentInstanceServiceNg2 } from '../../services/component-instance-services/component-instance.service'; +import { GetInstanceArtifactsByTypeAction, UpdateInstanceArtifactAction } from '../actions/instance-artifacts.actions'; +import { InstanceArtifactsState } from './instance-artifacts.state'; + +describe('Test Artifact State', () => { + + const heat1 = Mock.of({ + uniqueId: '1', artifactName: 'heat1', timeout: 0, artifactDisplayName: 'heat1', artifactGroupType: ArtifactGroupType.DEPLOYMENT + }); + + const heat1env = Mock.of({ + uniqueId: '2', artifactName: 'heat1env', timeout: 0, generatedFromId: '1', artifactDisplayName: 'heat1env', artifactGroupType: ArtifactGroupType.DEPLOYMENT + }); + + const storeMock = Mock.of( { dispatch : jest.fn() }); + + const artifacts = [ + heat1, + heat1env + ]; + + /** + * NGXS Store state before we run the update + */ + const ngxsState = { + deploymentArtifacts : artifacts + }; + + /** + * The ENV artifact that we wish to update + */ + const updatedArtifact = Mock.of({ + uniqueId: '2', artifactName: 'heat1env', timeout: 33, generatedFromId: '1', artifactDisplayName: 'heat1env-UPDATE', artifactGroupType: ArtifactGroupType.DEPLOYMENT + }); + + const componentInstanceServiceMock: ComponentInstanceServiceNg2 = Mock.of({ + updateInstanceArtifact: jest.fn().mockImplementation(() => Observable.of(updatedArtifact)), + getComponentInstanceArtifactsByGroupType: jest.fn().mockImplementation(() => Observable.of([heat1, updatedArtifact])) + }); + + const actionMock: UpdateInstanceArtifactAction = Mock.of({ + payload: { + componentType: '', + componentId: '', + instanceId: '', + artifact: updatedArtifact + } + }); + + it('Test that HEAT timeout is updated', () => { + const state: InstanceArtifactsState = new InstanceArtifactsState(storeMock, componentInstanceServiceMock); + const context = { getState: jest.fn().mockImplementation(() => ngxsState), patchState: jest.fn(), setState: jest.fn(), dispatch: jest.fn() }; + state.updateArtifact(context, actionMock ).subscribe( (v) => console.log('OK')); + expect(storeMock.dispatch).toBeCalled(); + }); + +}); diff --git a/catalog-ui/src/app/ng2/store/states/artifacts.state.ts b/catalog-ui/src/app/ng2/store/states/artifacts.state.ts new file mode 100644 index 0000000000..64efbe96a9 --- /dev/null +++ b/catalog-ui/src/app/ng2/store/states/artifacts.state.ts @@ -0,0 +1,140 @@ +/** + * Created by ob0695 on 7/17/2018. + */ +import { Action, Selector, State, StateContext } from '@ngxs/store'; +import * as _ from 'lodash'; +import { tap } from 'rxjs/operators'; +import { ArtifactModel } from '../../../models/artifacts'; +import { ArtifactGroupType } from '../../../utils/constants'; +import { TopologyTemplateService } from '../../services/component-services/topology-template.service'; +import { ComponentGenericResponse } from '../../services/responses/component-generic-response'; +import { ServiceGenericResponse } from '../../services/responses/service-generic-response'; +import { CreateOrUpdateArtifactAction, DeleteArtifactAction, GetArtifactsByTypeAction } from '../actions/artifacts.action'; + +export interface ArtifactsStateModel { + artifacts: ArtifactModel[]; + deploymentArtifacts: ArtifactModel[]; + toscaArtifacts: ArtifactModel[]; + serviceApiArtifacts: ArtifactModel[]; +} + +@State({ + name: 'artifacts', + defaults: { + artifacts: [], + deploymentArtifacts: [], + toscaArtifacts: [], + serviceApiArtifacts: [] + } +}) + +export class ArtifactsState { + + constructor(protected topologyTemplateService: TopologyTemplateService) { + } + + @Selector() + static getEnvArtifact(state: ArtifactsStateModel, heatEnvArtifact: ArtifactModel) { + return (heatEnvArtifact: ArtifactModel) => { + _.find(state.deploymentArtifacts, (artifact)=> { + return artifact.generatedFromId === heatEnvArtifact.uniqueId + }) + }; + } + + @Selector() + static getArtifactsByType(state: ArtifactsStateModel, type: string) { + return (type: string) => { + switch (type) { + case ArtifactGroupType.TOSCA: + return state.toscaArtifacts; + case ArtifactGroupType.INFORMATION: + return state.artifacts; + case ArtifactGroupType.DEPLOYMENT: + return state.deploymentArtifacts; + case ArtifactGroupType.SERVICE_API: + return state.serviceApiArtifacts; + } + }; + } + + private updateArtifactState = (artifactsState: ArtifactModel[], artifactToUpdate: ArtifactModel, updatedArtifact: ArtifactModel) => { + if (!artifactToUpdate.uniqueId) { // Create Artifact + return [...artifactsState, updatedArtifact] + } else { // Update Artifact + let artifactToUpdateIndex = _.findIndex(artifactsState, (artifact) => { + return artifact.uniqueId === artifactToUpdate.uniqueId + }) + let artifacts = Array.from(artifactsState); + artifacts[artifactToUpdateIndex] = updatedArtifact; + return [...artifacts]; + } + } + + @Action(GetArtifactsByTypeAction) + getArtifactsByType({getState, patchState}: StateContext, action: GetArtifactsByTypeAction) { + const state = getState(); + return this.topologyTemplateService.getArtifactsByType(action.payload.componentType, action.payload.componentId, action.payload.artifactType) + .pipe(tap((resp: ComponentGenericResponse) => { + switch (action.payload.artifactType) { + case ArtifactGroupType.INFORMATION: + patchState({ + artifacts: _.values(resp.artifacts) + }); + + case ArtifactGroupType.DEPLOYMENT: + patchState({ + deploymentArtifacts: _.values(resp.deploymentArtifacts) + }); + + case ArtifactGroupType.TOSCA: + patchState({ + toscaArtifacts: _.values(resp.toscaArtifacts) + }); + + case ArtifactGroupType.SERVICE_API: + patchState({ + serviceApiArtifacts: _.values((resp).serviceApiArtifacts) + }); + } + })); + } + + @Action(CreateOrUpdateArtifactAction) + createOrUpdateArtifact({getState, patchState}: StateContext, action: CreateOrUpdateArtifactAction) { + const state = getState(); + return this.topologyTemplateService.addOrUpdateArtifact(action.payload.componentType, action.payload.componentId, action.payload.artifact) + .pipe(tap((resp: ArtifactModel) => { + + switch (resp.artifactGroupType) { + case ArtifactGroupType.DEPLOYMENT: + patchState({ + deploymentArtifacts: this.updateArtifactState(state.deploymentArtifacts, action.payload.artifact, resp) + }); + + case ArtifactGroupType.INFORMATION: + patchState({ + artifacts: this.updateArtifactState(state.artifacts, action.payload.artifact, resp) + }); + } + })); + } + + @Action(DeleteArtifactAction) + deleteArtifact({getState, patchState}: StateContext, action: DeleteArtifactAction) { + const state = getState(); + return this.topologyTemplateService.deleteArtifact(action.payload.componentId, action.payload.componentType, action.payload.artifact.uniqueId, action.payload.artifact.artifactLabel) + .pipe(tap((resp: ArtifactModel) => { + switch (resp.artifactGroupType) { + case ArtifactGroupType.DEPLOYMENT: + patchState({ + deploymentArtifacts: state.deploymentArtifacts.filter(({uniqueId}) => uniqueId !== action.payload.artifact.uniqueId) + }); + case ArtifactGroupType.INFORMATION: + patchState({ + artifacts: state.artifacts.filter(({uniqueId}) => uniqueId !== action.payload.artifact.uniqueId) + }); + } + })); + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/store/states/instance-artifacts.state.ts b/catalog-ui/src/app/ng2/store/states/instance-artifacts.state.ts new file mode 100644 index 0000000000..12ba1ae7ba --- /dev/null +++ b/catalog-ui/src/app/ng2/store/states/instance-artifacts.state.ts @@ -0,0 +1,145 @@ +/** + * Created by ob0695 on 7/17/2018. + */ +import { Action, Selector, State, StateContext, Store } from '@ngxs/store'; +import * as _ from 'lodash'; +import { tap } from 'rxjs/operators'; +import { ArtifactModel } from '../../../models/artifacts'; +import { ArtifactGroupType } from '../../../utils/constants'; +import { ComponentInstanceServiceNg2 } from '../../services/component-instance-services/component-instance.service'; +import { ComponentGenericResponse } from '../../services/responses/component-generic-response'; +import { + CreateInstanceArtifactAction, + DeleteInstanceArtifactAction, + GetInstanceArtifactsByTypeAction, + UpdateInstanceArtifactAction +} from '../actions/instance-artifacts.actions'; +import { ArtifactsStateModel } from './artifacts.state'; + +export interface InstanceArtifactsStateModel { + artifacts: ArtifactModel[]; + deploymentArtifacts: ArtifactModel[]; +} + +@State({ + name: 'instance_artifacts', + defaults: { + artifacts: [], + deploymentArtifacts: [] + } +}) +export class InstanceArtifactsState { + + constructor(private store: Store, protected componentInstanceService: ComponentInstanceServiceNg2) { + } + + @Selector() + static getArtifactsByType(state: InstanceArtifactsStateModel) { + return (type: string) => { + switch (type) { + case ArtifactGroupType.INFORMATION: + return state.artifacts; + case ArtifactGroupType.DEPLOYMENT: + return state.deploymentArtifacts; + } + }; + } + + @Action(GetInstanceArtifactsByTypeAction) + getInstanceArtifactsByType({getState, patchState}: StateContext, action: GetInstanceArtifactsByTypeAction) { + const state = getState(); + return this.componentInstanceService.getComponentInstanceArtifactsByGroupType(action.payload.componentType, action.payload.componentId, action.payload.instanceId, action.payload.artifactType) + .pipe(tap((resp: ComponentGenericResponse) => { + switch (action.payload.artifactType) { + case ArtifactGroupType.INFORMATION: + patchState({ + artifacts: _.values(resp) as ArtifactModel[] + }); + break; + case ArtifactGroupType.DEPLOYMENT: + patchState({ + deploymentArtifacts: _.values(resp) as ArtifactModel[] + }); + break; + } + })); + } + + @Action(CreateInstanceArtifactAction) + createArtifact({getState, patchState}: StateContext, action: CreateInstanceArtifactAction) { + const state = getState(); + return this.componentInstanceService.addInstanceArtifact(action.payload.componentType, action.payload.componentId, action.payload.instanceId, action.payload.artifact) + .pipe(tap((resp: ArtifactModel) => { + switch (resp.artifactGroupType) { + case ArtifactGroupType.DEPLOYMENT: + patchState({ + deploymentArtifacts: [...state.deploymentArtifacts, resp] + }); + break; + case ArtifactGroupType.INFORMATION: + patchState({ + artifacts: [...state.artifacts, resp] + }); + break; + } + })); + } + + @Action(UpdateInstanceArtifactAction) + updateArtifact({getState, patchState}: StateContext, action: UpdateInstanceArtifactAction) { + const state = getState(); + return this.componentInstanceService.updateInstanceArtifact(action.payload.componentType, action.payload.componentId, action.payload.instanceId, action.payload.artifact) + .pipe(tap((resp: ArtifactModel) => { + switch (resp.artifactGroupType) { + case ArtifactGroupType.DEPLOYMENT: + // We cannot simply update the updated artifact state because updating a deployment ENV file may cause an update to his parent HEAT + // file. + // Just dispatch an action to refresh the deployment artifacts list + this.store.dispatch(new GetInstanceArtifactsByTypeAction(({ + componentType: action.payload.componentType, + componentId: action.payload.componentId, + instanceId: action.payload.instanceId, + artifactType: ArtifactGroupType.DEPLOYMENT + }))); + break; + case ArtifactGroupType.INFORMATION: + patchState({ + artifacts: this.updateInstanceArtifactState(state.artifacts, action.payload.artifact, resp) + }); + break; + } + })); + } + + @Action(DeleteInstanceArtifactAction) + deleteInstanceArtifact({getState, patchState}: StateContext, action: DeleteInstanceArtifactAction) { + const state = getState(); + return this.componentInstanceService. + deleteInstanceArtifact(action.payload.componentId, action.payload.componentType, action.payload.instanceId, action.payload.artifact.uniqueId, action.payload.artifact.artifactLabel) + .pipe(tap((resp: ArtifactModel) => { + switch (resp.artifactGroupType) { + case ArtifactGroupType.DEPLOYMENT: + patchState({ + deploymentArtifacts: state.deploymentArtifacts.filter(({uniqueId}) => uniqueId !== action.payload.artifact.uniqueId) + }); + break; + case ArtifactGroupType.INFORMATION: + patchState({ + artifacts: state.artifacts.filter(({uniqueId}) => uniqueId !== action.payload.artifact.uniqueId) + }); + break; + } + })); + } + + private updateInstanceArtifactState = (artifactsState: ArtifactModel[], artifactToUpdate: ArtifactModel, updatedArtifact: ArtifactModel) => { + const artifactToUpdateIndex = _.findIndex(artifactsState, (artifact) => { + return artifact.uniqueId === artifactToUpdate.uniqueId; + }); + const artifacts = Array.from(artifactsState); + artifacts[artifactToUpdateIndex] = updatedArtifact; + const ret = [...artifacts]; + return ret; + } + +} diff --git a/catalog-ui/src/app/ng2/store/states/workspace.state.ts b/catalog-ui/src/app/ng2/store/states/workspace.state.ts new file mode 100644 index 0000000000..eb8200f6e0 --- /dev/null +++ b/catalog-ui/src/app/ng2/store/states/workspace.state.ts @@ -0,0 +1,48 @@ +/** + * Created by ob0695 on 7/17/2018. + */ +import {State, Action, StateContext} from '@ngxs/store'; +import {UpdateIsDesigner, UpdateIsViewOnly} from "../actions/workspace.action"; +import {Selector} from "@ngxs/store"; + +export interface WorkspaceStateModel { + isViewOnly: boolean; + isDesigner: boolean; +} + +@State({ + name: 'workspace', + defaults: { + isViewOnly: false, + isDesigner: true + } +}) + +export class WorkspaceState { + + constructor(){} + + @Selector() static isViewOnly(state: WorkspaceStateModel):boolean { + return state.isViewOnly; + } + @Selector() static isDesigner(state: WorkspaceStateModel): boolean { + return state.isDesigner; + } + + @Action(UpdateIsViewOnly) + updateIsViewOnly({getState, setState}: StateContext, action:UpdateIsViewOnly) { + const state = getState(); + setState({ + ...state, + isViewOnly: action.isViewOnly + }); + } + + @Action(UpdateIsDesigner) + updateIsDesigner({getState, patchState}: StateContext, action:UpdateIsDesigner) { + const state = getState(); + patchState({ + isDesigner: action.isDesigner + }); + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/utils/ng1-upgraded-provider.ts b/catalog-ui/src/app/ng2/utils/ng1-upgraded-provider.ts index fcb21c0c83..aab531d205 100644 --- a/catalog-ui/src/app/ng2/utils/ng1-upgraded-provider.ts +++ b/catalog-ui/src/app/ng2/utils/ng1-upgraded-provider.ts @@ -23,13 +23,12 @@ */ import { DataTypesService } from "../../services/data-types-service"; import ICacheObject = angular.ICacheObject; -import { SharingService } from "../../services/sharing-service"; import { CookieService } from "../../services/cookie-service"; -import { CacheService } from "../../services/cache-service"; import {ComponentFactory} from "../../utils/component-factory" import { EventListenerService } from "app/services/event-listener-service"; import { ModalsHandler } from "app/utils"; import IScope = angular.IScope; +import { SharingService } from "../services/sharing.service"; /** Services we need to upgrade from angular1 to angular2 - in the future we need to rewrite them all to angular2 **/ @@ -61,10 +60,6 @@ export function scopeServiceFactory(cacheObj: ICacheObject) { return cacheObj.get('$scope'); } -export function cacheServiceFactory(cacheObj: ICacheObject) { - return cacheObj.get('Sdc.Services.CacheService'); -} - export function eventListenerServiceServiceFactory(cacheObj: ICacheObject) { return cacheObj.get('EventListenerService'); } @@ -73,6 +68,10 @@ export function notificationServiceFactory(cacheObj: ICacheObject) { return cacheObj.get('Notification'); } +export function ModalsHandlerFactory(cacheObj: ICacheObject) { + return cacheObj.get('ModalsHandler'); +} + export const ComponentFactoryProvider = { provide: ComponentFactory, @@ -80,18 +79,12 @@ export const ComponentFactoryProvider = { deps: ['$injector'] }; - -export function ModalsHandlerFactory(cacheObj: ICacheObject) { - return cacheObj.get('ModalsHandler'); -} - export const DataTypesServiceProvider = { provide: DataTypesService, useFactory: dataTypesServiceFactory, deps: ['$injector'] }; - export const SharingServiceProvider = { provide: SharingService, useFactory: sharingServiceFactory, @@ -122,17 +115,12 @@ export const StateParamsServiceFactory = { useFactory: stateParamsServiceFactory, deps: ['$injector'] }; -export const CacheServiceProvider = { - provide: CacheService, - useFactory: cacheServiceFactory, - deps: ['$injector'] -}; - -export const EventListenerServiceProvider = { - provide: EventListenerService, - useFactory: eventListenerServiceServiceFactory, - deps: ['$injector'] -}; +// +// export const EventListenerServiceProvider = { +// provide: EventListenerService, +// useFactory: eventListenerServiceServiceFactory, +// deps: ['$injector'] +// }; export const NotificationServiceProvider = { provide: 'Notification', @@ -144,4 +132,4 @@ export const ModalsHandlerProvider = { provide: ModalsHandler, useFactory: ModalsHandlerFactory, deps: ['$injector'] -} +}; diff --git a/catalog-ui/src/app/ng2/utils/queue-service-utils.ts b/catalog-ui/src/app/ng2/utils/queue-service-utils.ts new file mode 100644 index 0000000000..8cf7f98383 --- /dev/null +++ b/catalog-ui/src/app/ng2/utils/queue-service-utils.ts @@ -0,0 +1,58 @@ +/** + * Created by ob0695 on 6/3/2018. + */ +/*- + * ============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========================================================= + */ +import {Injectable} from "@angular/core"; + +@Injectable() +export class QueueServiceUtils { + + private executionQueue:any; + + constructor() { + if(!this.executionQueue) { + this.executionQueue = this.getQueue(); + } + } + + private getQueue = () => new Promise((resolve, reject) => { + resolve(true); + }); + + 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/src/app/services-ng2.ts b/catalog-ui/src/app/services-ng2.ts new file mode 100644 index 0000000000..e2811ba68d --- /dev/null +++ b/catalog-ui/src/app/services-ng2.ts @@ -0,0 +1,27 @@ +// Angular 2 services +export * from './ng2/services/config.service'; +export * from './ng2/services/authentication.service'; +export * from './ng2/services/user.service'; +export * from './ng2/services/data-type.service'; +export * from './ng2/services/modal.service'; +export * from './ng2/services/plugins.service'; +export * from './ng2/services/sharing.service'; +export * from './ng2/services/cache.service'; +export * from './ng2/services/cookie.service'; +export * from './ng2/services/home.service'; +export * from './ng2/services/catalog.service'; +export * from './ng2/services/policies.service'; +export * from './ng2/services/properties.service'; +export * from './ng2/services/window.service'; +export * from './ng2/services/dynamic-component.service'; +export * from './ng2/services/event-bus.service'; +export * from './ng2/services/groups.service'; + +export * from './ng2/services/component-services/component.service'; +export * from './ng2/services/component-services/component.service.factory'; +export * from './ng2/services/component-services/service.service'; +export * from './ng2/services/component-services/resource.service'; +export * from './ng2/services/component-services/component-mode.service'; + +export * from './ng2/services/onboarding.service'; +export * from './ng2/components/modals/onboarding-modal/import-vsp.service' diff --git a/catalog-ui/src/app/services.ts b/catalog-ui/src/app/services.ts index 79b5132634..be77fed951 100644 --- a/catalog-ui/src/app/services.ts +++ b/catalog-ui/src/app/services.ts @@ -21,9 +21,7 @@ /** * Created by ob0695 on 2/23/2017. */ -export * from './services/activity-log-service'; export * from './services/available-icons-service'; -export * from './services/cache-service'; export * from './services/configuration-ui-service'; export * from './services/category-resource-service'; export * from './services/components/component-service'; @@ -37,14 +35,10 @@ export * from './services/category-resource-service'; export * from './services/cookie-service'; export * from './services/data-types-service'; export * from './services/ecomp-service'; -export * from './services/entity-service'; export * from './services/event-listener-service'; export * from './services/header-interceptor'; export * from './services/loader-service'; -export * from './services/onboarding-service'; export * from './services/progress-service'; export * from './services/sdc-version-service'; -export * from './services/sharing-service'; export * from './services/url-tobase64-service'; export * from './services/angular-js-bridge-service'; - diff --git a/catalog-ui/src/app/services/activity-log-service.ts b/catalog-ui/src/app/services/activity-log-service.ts deleted file mode 100644 index 97d26d4f44..0000000000 --- a/catalog-ui/src/app/services/activity-log-service.ts +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {Activity} from "../models/activity"; -import {IAppConfigurtaion, IApi} from "../models/app-config"; - -// Define an interface of the object you want to use, providing it's properties -export interface IActivityLogService { - getActivityLogService(type:string, id:string):ng.IPromise>; -} - -export class ActivityLogService implements IActivityLogService { - - - static '$inject' = ['$http', '$q', 'sdcConfig']; - private api:IApi; - - constructor(private $http:ng.IHttpService, private $q:ng.IQService, sdcConfig:IAppConfigurtaion) { - this.api = sdcConfig.api; - } - - getActivityLogService = (type:string, id:string):ng.IPromise> => { - let defer = this.$q.defer(); - this.$http.get(this.api.root + this.api.GET_activity_log.replace(':type', type).replace(':id', id)) - .then((activityLog:any) => { - defer.resolve(activityLog.data); - }); - return defer.promise; - } -} diff --git a/catalog-ui/src/app/services/cache-service.ts b/catalog-ui/src/app/services/cache-service.ts deleted file mode 100644 index 4d10db0066..0000000000 --- a/catalog-ui/src/app/services/cache-service.ts +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {Dictionary} from "app/utils"; - -interface ICacheService { - get(key:string):any; - set(key:string, value:any):void; -} - -export class CacheService implements ICacheService { - - private storage:Dictionary; - - constructor() { - this.storage = new Dictionary(); - }; - - public get = (key:string):any => { - return this.storage.getValue(key); - }; - - public set = (key:string, value:any):void => { - this.storage.setValue(key, value); - }; - - public remove = (key:string):void => { - if (this.storage.containsKey(key)) { - this.storage.remove(key); - } - }; - - public contains = (key:string):boolean => { - return this.storage.containsKey(key); - }; -} diff --git a/catalog-ui/src/app/services/components/component-service.ts b/catalog-ui/src/app/services/components/component-service.ts index 25203e7732..c7ab975e6e 100644 --- a/catalog-ui/src/app/services/components/component-service.ts +++ b/catalog-ui/src/app/services/components/component-service.ts @@ -22,7 +22,7 @@ import * as _ from "lodash"; import {ArtifactModel, IFileDownload, InstancesInputsPropertiesMap, InputModel, IValidate, RelationshipModel, PropertyModel, Component, ComponentInstance, AttributeModel, IAppConfigurtaion, Resource, Module, DisplayModule, ArtifactGroupModel, InputsAndProperties} from "app/models"; import {ComponentInstanceFactory, CommonUtils} from "app/utils"; -import {SharingService} from "../sharing-service"; +import {SharingService} from "app/services-ng2"; import {ComponentMetadata} from "../../models/component-metadata"; export interface IComponentService { @@ -683,7 +683,6 @@ export class ComponentService implements IComponentService { public getComponentInstanceProperties = (componentId:string, instanceId:string):ng.IPromise> => { - let deferred = this.$q.defer>(); this.restangular.one(componentId).one("componentInstances").one(instanceId).one("properties").get().then((response:any) => { console.log("component instance properties return successfully: ", response); diff --git a/catalog-ui/src/app/services/components/resource-service.ts b/catalog-ui/src/app/services/components/resource-service.ts index cb30107a69..3a00da1171 100644 --- a/catalog-ui/src/app/services/components/resource-service.ts +++ b/catalog-ui/src/app/services/components/resource-service.ts @@ -25,7 +25,7 @@ import * as _ from "lodash"; import {IComponentService, ComponentService} from "./component-service"; import {PropertyModel, IAppConfigurtaion, Resource, Component} from "../../models"; -import {SharingService} from "../sharing-service"; +import {SharingService} from "app/services-ng2"; export interface IResourceService extends IComponentService { updateResourceGroupProperties(uniqueId:string, groupId:string, properties:Array):ng.IPromise> diff --git a/catalog-ui/src/app/services/components/service-service.ts b/catalog-ui/src/app/services/components/service-service.ts index f258c7be98..6c318bd6d6 100644 --- a/catalog-ui/src/app/services/components/service-service.ts +++ b/catalog-ui/src/app/services/components/service-service.ts @@ -25,7 +25,7 @@ import * as _ from "lodash"; import {IComponentService, ComponentService} from "./component-service"; import {Distribution, DistributionComponent, Service, PropertyModel, Component, IAppConfigurtaion} from "app/models"; -import {SharingService} from "../sharing-service"; +import {SharingService} from "app/services-ng2"; export interface IServiceService extends IComponentService { getDistributionsList(uuid:string):ng.IPromise>; diff --git a/catalog-ui/src/app/services/components/utils/composition-left-palette-service.ts b/catalog-ui/src/app/services/components/utils/composition-left-palette-service.ts index 99be788547..b47c5e019b 100644 --- a/catalog-ui/src/app/services/components/utils/composition-left-palette-service.ts +++ b/catalog-ui/src/app/services/components/utils/composition-left-palette-service.ts @@ -32,11 +32,13 @@ import {ComponentMetadata} from "app/models/component-metadata"; import {GroupMetadata, GroupTpes} from "app/models/group-metadata"; import {PolicyMetadata, PolicyTpes} from "app/models/policy-metadata"; import {Resource} from "app/models/components/resource"; +import IHttpPromiseCallbackArg = angular.IHttpPromiseCallbackArg; export class LeftPaletteLoaderService { static '$inject' = [ 'Restangular', + '$http', 'sdcConfig', '$q', 'ComponentFactory', @@ -45,6 +47,7 @@ export class LeftPaletteLoaderService { ]; constructor(protected restangular:restangular.IElement, + protected $http:ng.IHttpService, protected sdcConfig:IAppConfigurtaion, protected $q:ng.IQService, protected ComponentFactory:ComponentFactory, @@ -64,7 +67,9 @@ export class LeftPaletteLoaderService { private updateLeftPalette = (componentInternalType:string):void => { /* add components */ - this.restangular.one("resources").one('/latestversion/notabstract/metadata').get({'internalComponentType': componentInternalType}).then((leftPaletteComponentMetadata:Array) => { + const leftPaletteUrl = this.sdcConfig.api.uicache_root + this.sdcConfig.api.GET_uicache_left_palette; + this.$http.get(leftPaletteUrl, {params: {'internalComponentType': componentInternalType}}).then((res) => res.data).then((leftPaletteComponentMetadata:Array) => { + // this.restangular.one("resources").one('/latestversion/notabstract/metadata').get({'internalComponentType': componentInternalType}).then((leftPaletteComponentMetadata:Array) => { _.forEach(leftPaletteComponentMetadata, (componentMetadata:ComponentMetadata) => { this.leftPanelComponents.push(new LeftPaletteComponent(LeftPaletteMetadataTypes.Component, componentMetadata)); }); diff --git a/catalog-ui/src/app/services/entity-service.ts b/catalog-ui/src/app/services/entity-service.ts deleted file mode 100644 index 2e7b2e1eed..0000000000 --- a/catalog-ui/src/app/services/entity-service.ts +++ /dev/null @@ -1,104 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import * as _ from "lodash"; -import { Service, IApi, IAppConfigurtaion, Resource, Component} from "../models"; -import {SharingService} from "./sharing-service"; -import {ComponentFactory} from "../utils/component-factory"; -import {CacheService} from "./cache-service"; -import {ResourceType} from "app/utils"; - -interface IEntityService { - getAllComponents(smallObjects?:boolean):ng.IPromise>; -} - -interface IComponentsArray { - services:Array; - resources:Array; -} - -export class EntityService implements IEntityService { - static '$inject' = ['$http', '$q', 'sdcConfig', 'Sdc.Services.SharingService', 'ComponentFactory', 'Sdc.Services.CacheService']; - private _smallObjectAttributes = ['uniqueId', 'name', 'componentType', 'resourceType', 'lastUpdateDate', 'lifecycleState', 'distributionStatus', 'icon', 'version']; - private api:IApi; - - constructor(private $http:ng.IHttpService, - private $q:ng.IQService, - private sdcConfig:IAppConfigurtaion, - private sharingService:SharingService, - private ComponentFactory:ComponentFactory, - private cacheService:CacheService) { - this.api = sdcConfig.api; - } - - getCatalog = ():ng.IPromise> => { - let defer = this.$q.defer>(); - this.$http.get(this.api.root + this.api.GET_catalog, {params: {excludeTypes: [ResourceType.VFCMT, ResourceType.CONFIGURATION]}}) - .then((response:any) => { - let followedResponse: IComponentsArray = response.data; - let componentsList:Array = new Array(); - - followedResponse.services && followedResponse.services.forEach((serviceResponse:Service) => { - let component:Service = this.ComponentFactory.createService(serviceResponse); // new Service(serviceResponse); - componentsList.push(component); - this.sharingService.addUuidValue(component.uniqueId, component.uuid); - }); - - followedResponse.resources && followedResponse.resources.forEach((resourceResponse:Resource) => { - let component:Resource = this.ComponentFactory.createResource(resourceResponse); - componentsList.push(component); - this.sharingService.addUuidValue(component.uniqueId, component.uuid); - }); - - defer.resolve(componentsList); - },(responce) => { - defer.reject(responce); - }); - return defer.promise; - }; - - getAllComponents = (smallObjects?:boolean):ng.IPromise> => { - let defer = this.$q.defer>(); - this.$http.get(this.api.root + this.api.GET_element) - .then((response:any) => { - let componentResponse:IComponentsArray = response.data; - let componentsList:Array = []; - - componentResponse.services && componentResponse.services.forEach((serviceResponse:Service) => { - serviceResponse = (smallObjects) ? _.pick(serviceResponse, this._smallObjectAttributes) : serviceResponse; - let component:Service = this.ComponentFactory.createService(serviceResponse); - componentsList.push(component); - this.sharingService.addUuidValue(component.uniqueId, component.uuid); - }); - - componentResponse.resources && componentResponse.resources.forEach((resourceResponse:Resource) => { - resourceResponse = (smallObjects) ? _.pick(resourceResponse, this._smallObjectAttributes) : resourceResponse; - let component:Resource = this.ComponentFactory.createResource(resourceResponse); - componentsList.push(component); - this.sharingService.addUuidValue(component.uniqueId, component.uuid); - }); - - defer.resolve(componentsList); - }); - - return defer.promise; - }; -} diff --git a/catalog-ui/src/app/services/event-listener-service.ts b/catalog-ui/src/app/services/event-listener-service.ts index 360edad700..2d3c4a6fc8 100644 --- a/catalog-ui/src/app/services/event-listener-service.ts +++ b/catalog-ui/src/app/services/event-listener-service.ts @@ -23,22 +23,21 @@ 'use strict'; import * as _ from "lodash"; import {Dictionary} from "../utils/dictionary/dictionary"; +import {Injectable} from "@angular/core"; -interface IEventListenerService { - -} interface ICallbackData { - callback:Function; - args:any[]; + callback: Function; + args: any[]; } -export class EventListenerService implements IEventListenerService { +@Injectable() +export class EventListenerService { - public observerCallbacks:Dictionary = new Dictionary>(); + public observerCallbacks: Dictionary = new Dictionary>(); //register an observer + callback - public registerObserverCallback = (eventName:string, callback:Function, ...args) => { + public registerObserverCallback = (eventName: string, callback: Function, ...args) => { let callbackData = { callback: callback, args: args @@ -62,11 +61,11 @@ export class EventListenerService implements IEventListenerService { }; //unregister an observer - public unRegisterObserver = (eventName:string, callbackFunc?:Function) => { + public unRegisterObserver = (eventName: string, callbackFunc?: Function) => { if (this.observerCallbacks.containsKey(eventName)) { - let callbacks: ICallbackData[] = this.observerCallbacks.getValue(eventName); - if(callbacks.length === 1) { + let callbacks: ICallbackData[] = this.observerCallbacks.getValue(eventName); + if (callbacks.length === 1) { this.observerCallbacks.remove(eventName); } else { let filterCallbacks = _.filter(callbacks, (callBackObj) => { @@ -74,13 +73,12 @@ export class EventListenerService implements IEventListenerService { }); this.observerCallbacks.setValue(eventName, filterCallbacks); } - } }; - public notifyObservers = function (eventName:string, ...args) { - _.forEach(this.observerCallbacks.getValue(eventName), (callbackData:ICallbackData) => { - callbackData.callback(...args); - }); + public notifyObservers = function (eventName: string, ...args) { + _.forEach(this.observerCallbacks.getValue(eventName), (callbackData: ICallbackData) => { + callbackData.callback(...args); + }); }; } diff --git a/catalog-ui/src/app/services/header-interceptor.ts b/catalog-ui/src/app/services/header-interceptor.ts index 931b292d60..5f4819ae88 100644 --- a/catalog-ui/src/app/services/header-interceptor.ts +++ b/catalog-ui/src/app/services/header-interceptor.ts @@ -7,9 +7,9 @@ * 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. @@ -19,17 +19,19 @@ */ 'use strict'; -import {IAppConfigurtaion} from "../models/app-config"; -import {Dictionary} from "../utils/dictionary/dictionary"; -import {SharingService} from "./sharing-service"; - -//Method name should be exactly "response" - http://docs.angularjs.org/api/ng/service/$http -export interface IInterceptor { - request:Function; +import { SharingService } from 'app/services-ng2'; +import { IAppConfigurtaion } from '../models/app-config'; +import { ServerErrorResponse } from '../models/server-error-response'; +import { Dictionary } from '../utils/dictionary/dictionary'; +// Method name should be exactly "response" - http://docs.angularjs.org/api/ng/service/$http +export interface Interceptor { + request: Function; + response: Function; + responseError: Function; } -export class HeaderInterceptor implements IInterceptor { +export class HeaderInterceptor implements Interceptor { public static $inject = [ '$injector', '$q', @@ -39,51 +41,55 @@ export class HeaderInterceptor implements IInterceptor { '$location' ]; - public static Factory($injector:ng.auto.IInjectorService, - $q:ng.IQService, - uuid4:any, - sharingService:SharingService, - sdcConfig:IAppConfigurtaion, - $location:ng.ILocationService) { - return new HeaderInterceptor($injector, $q, uuid4, sharingService, sdcConfig, $location); - } - - constructor(private $injector:ng.auto.IInjectorService, - private $q:ng.IQService, - private uuid4:any, - private sharingService:SharingService, - private sdcConfig:IAppConfigurtaion, - private $location:ng.ILocationService) { - console.debug('header-interceptor: initializing AuthenticationInterceptor'); + constructor(private $injector: ng.auto.IInjectorService, + private $q: ng.IQService, + private uuid4: any, + private sharingService: SharingService, + private sdcConfig: IAppConfigurtaion, + private $location: ng.ILocationService) { } - public request = (requestSuccess):ng.IPromise => { + public request = (requestSuccess): ng.IPromise => { requestSuccess.headers['X-ECOMP-RequestID'] = this.uuid4.generate(); /** * For every request to the server, that the service id, or resource id is sent in the URL, need to pass UUID in the header. * Check if the unique id exists in uuidMap, and if so get the UUID and add it to the header. */ - let map:Dictionary = this.sharingService.getUuidMap(); + const map: Dictionary = this.sharingService.getUuidMap(); if (map && requestSuccess.url.indexOf(this.sdcConfig.api.root) === 0) { - console.log("header-interceptor: url: " + requestSuccess.url); - map.forEach((key:string) => { + map.forEach((key: string) => { if (requestSuccess.url.indexOf(key) !== -1) { requestSuccess.headers['X-ECOMP-ServiceID'] = this.sharingService.getUuidValue(key); } }); } return requestSuccess; - }; + } - public response = (responseSuccess):ng.IPromise => { - let responseData = responseSuccess.data; + public response = (responseSuccess): ng.IPromise => { + const responseData = responseSuccess.data; if (responseData) { - let data = JSON.stringify(responseData); - if (data && (data.indexOf("Global Logon: Login") > 0)) { + const data = JSON.stringify(responseData); + if (data && (data.indexOf('Global Logon: Login') > 0)) { this.$location.path('dashboard/welcome'); window.location.reload(); } } return responseSuccess; } + + public responseError = (response): ng.IPromise => { + const errorResponse: ServerErrorResponse = new ServerErrorResponse(response, true); + const modalService = this.$injector.get('ModalServiceSdcUI'); + + const errorDetails = { + 'Error Code': errorResponse.messageId, + 'Status Code': errorResponse.status + }; + if (errorResponse.ecompRequestId) { + errorDetails['Transaction ID'] = errorResponse.ecompRequestId; + } + modalService.openErrorDetailModal('Error', errorResponse.message, 'error-modal', errorDetails); + return this.$q.reject(errorResponse); + } } diff --git a/catalog-ui/src/app/services/http-error-interceptor.ts b/catalog-ui/src/app/services/http-error-interceptor.ts deleted file mode 100644 index cef8c30716..0000000000 --- a/catalog-ui/src/app/services/http-error-interceptor.ts +++ /dev/null @@ -1,119 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {IServerMessageModalModel} from "../view-models/modals/message-modal/message-server-modal/server-message-modal-view-model"; -import {SEVERITY} from "../utils/constants"; -import 'app/utils/prototypes.ts'; - -export class HttpErrorInterceptor { - public static $inject = ['$injector', '$q']; - - public static Factory($injector:ng.auto.IInjectorService, $q:angular.IQService) { - return new HttpErrorInterceptor($injector, $q); - } - - constructor(private $injector:ng.auto.IInjectorService, private $q:angular.IQService) { - } - - public formatMessageArrays = (message:string, variables:Array)=> { - return message.replace(/\[%(\d+)\]/g, function (_, m) { - let tmp = []; - let list = variables[--m].split(";"); - list.forEach(function (item) { - tmp.push("
  • " + item + "
  • "); - }); - return "
      " + tmp.join("") + "
    "; - }); - }; - - public responseError = (rejection:any)=> { - - let text:string; - let variables; - let messageId:string = ""; - let isKnownException = false; - - if (rejection.data && rejection.data.serviceException) { - text = rejection.data.serviceException.text; - variables = rejection.data.serviceException.variables; - messageId = rejection.data.serviceException.messageId; - isKnownException = true; - } else if (rejection.data && rejection.data.requestError && rejection.data.requestError.serviceException) { - text = rejection.data.requestError.serviceException.text; - variables = rejection.data.requestError.serviceException.variables; - messageId = rejection.data.requestError.serviceException.messageId; - isKnownException = true; - } else if (rejection.data && rejection.data.requestError && rejection.data.requestError.policyException) { - text = rejection.data.requestError.policyException.text; - variables = rejection.data.requestError.policyException.variables; - messageId = rejection.data.requestError.policyException.messageId; - isKnownException = true; - } else if (rejection.data) { - text = 'Wrong error format from server'; - console.error(text); - isKnownException = false; - } - - let data:IServerMessageModalModel; - if (isKnownException) { - // Remove the "Error: " text at the begining - if (text.trim().indexOf("Error:") === 0) { - text = text.replace("Error:", "").trim(); - } - - //mshitrit DE199895 bug fix - let count:number = 0; - variables.forEach(function (item) { - variables[count] = item ? item.replace('<', '<').replace('>', '>') : ''; - count++; - }); - - // Format the message in case has array to
    • - text = this.formatMessageArrays(text, variables); - - // Format the message %1 %2 - text = text.format(variables); - - // Need to inject the MessageService manually to prevent circular componentsToUpgrade (because MessageService use $templateCache that use $http). - data = { - title: 'Error', - message: text, - messageId: messageId, - status: rejection.status, - severity: SEVERITY.ERROR - }; - } else { - // Need to inject the MessageService manually to prevent circular componentsToUpgrade (because MessageService use $templateCache that use $http). - data = { - title: 'Error', - message: rejection.status !== -1 ? rejection.statusText : "Error getting response from server", - messageId: messageId, - status: rejection.status, - severity: SEVERITY.ERROR - }; - } - - let modalsHandler = this.$injector.get('ModalsHandler'); - modalsHandler.openServerMessageModal(data); - - return this.$q.reject(rejection); - } -} diff --git a/catalog-ui/src/app/services/onboarding-service.ts b/catalog-ui/src/app/services/onboarding-service.ts deleted file mode 100644 index 3a6e940c6e..0000000000 --- a/catalog-ui/src/app/services/onboarding-service.ts +++ /dev/null @@ -1,112 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {Component, IComponent} from "../models/components/component"; -import {ICsarComponent} from "../models/csar-component"; -import {IAppConfigurtaion, IApi} from "../models/app-config"; -import {IFileDownload} from "../models/file-download"; -import {Resource} from "../models/components/resource"; -import {ComponentFactory} from "../utils/component-factory"; - -interface IOnboardingService { - getOnboardingComponents():ng.IPromise>; - getComponentFromCsarUuid(csarUuid:string):ng.IPromise; - downloadOnboardingCsar(packageId:string):ng.IPromise; -} - -export class OnboardingService implements IOnboardingService { - - static '$inject' = ['$http', '$q', 'sdcConfig', 'ComponentFactory']; - private api:IApi; - - constructor(private $http:ng.IHttpService, - private $q:ng.IQService, - private sdcConfig:IAppConfigurtaion, - private ComponentFactory:ComponentFactory) { - this.api = sdcConfig.api; - } - - getOnboardingVSPs = ():ng.IPromise> =>{ - let defer = this.$q.defer>(); - this.$http.get(this.api.GET_onboarding) - .then((response:any) => { - defer.resolve(response.data.results); - },(response) => { - defer.reject(response); - }); - - return defer.promise; - }; - - getOnboardingComponents = ():ng.IPromise> => { - let defer = this.$q.defer>(); - this.getOnboardingVSPs().then((onboardingComponents:Array) => { - let componentsList:Array = new Array(); - - onboardingComponents.forEach((obc:ICsarComponent) => { - let component:Component = this.ComponentFactory.createFromCsarComponent(obc); - componentsList.push(component); - }); - - defer.resolve(componentsList); - },(response) => { - defer.reject(response); - }); - - return defer.promise; - }; - - downloadOnboardingCsar = (packageId:string):ng.IPromise => { - let defer = this.$q.defer(); - this.$http({ - url: this.api.GET_onboarding + "/" + packageId, - method: "get", - responseType: "blob" - }) - .then((response:any) => { - defer.resolve(response.data); - }, (err) => { - defer.reject(err); - }); - - return defer.promise; - }; - - getComponentFromCsarUuid = (csarUuid:string):ng.IPromise => { - let defer = this.$q.defer(); - this.$http.get(this.api.root + this.api.GET_component_from_csar_uuid.replace(':csar_uuid', csarUuid)) - .then((response:any) => { - let component:Resource; - // If the status is 400, this means that the component not found. - // I do not want to return error from server, because a popup will appear in client with the error. - // So returning success (200) with status 400. - if (response.data.status !== 400) { - component = new Resource(null, this.$q, response.data); - } - defer.resolve(component); - },(response) => { - defer.reject(response.data); - }); - - return defer.promise; - }; - -} diff --git a/catalog-ui/src/app/services/sharing-service.ts b/catalog-ui/src/app/services/sharing-service.ts deleted file mode 100644 index f4cc2e6d5d..0000000000 --- a/catalog-ui/src/app/services/sharing-service.ts +++ /dev/null @@ -1,40 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {Dictionary} from "app/utils"; - -export class SharingService { - - private uuidMap:Dictionary = new Dictionary(); - - public getUuidValue = (uniqueId:string):string => { - return this.uuidMap.getValue(uniqueId); - }; - - public addUuidValue = (uniqueId:string, uuid:string):void => { - this.uuidMap.setValue(uniqueId, uuid); - }; - - public getUuidMap = ():Dictionary => { - return this.uuidMap; - }; - -} diff --git a/catalog-ui/src/app/utils.ts b/catalog-ui/src/app/utils.ts index 1d2eafb9fb..27c805a762 100644 --- a/catalog-ui/src/app/utils.ts +++ b/catalog-ui/src/app/utils.ts @@ -22,7 +22,6 @@ * Created by ob0695 on 2/23/2017. */ export * from './utils/dictionary/dictionary'; -export * from './utils/artifacts-utils'; export * from'./utils/file-utils' export * from './utils/validation-utils' export * from './utils/component-factory'; diff --git a/catalog-ui/src/app/utils/artifacts-utils.ts b/catalog-ui/src/app/utils/artifacts-utils.ts deleted file mode 100644 index e99b6411c4..0000000000 --- a/catalog-ui/src/app/utils/artifacts-utils.ts +++ /dev/null @@ -1,126 +0,0 @@ -/*- - * ============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========================================================= - */ - -import * as _ from "lodash"; -import {ArtifactModel} from "../models/artifacts"; -import {IArtifactResourceFormViewModelScope} from "../view-models/forms/artifact-form/artifact-form-view-model"; -import {Component} from "../models/components/component"; -import {ArtifactGroupType, ArtifactType} from "./constants"; - -export class ArtifactsUtils { - - static '$inject' = [ - '$filter' - ]; - - constructor(private $filter:ng.IFilterService) { - - } - - public getArtifactTypeByState(currentState:string):string { - switch (currentState) { - case "workspace.composition.lifecycle": - return "interface"; - case "workspace.composition.api": - return "api"; - case "workspace.deployment_artifacts": - case "workspace.composition.deployment": - return "deployment"; - case "workspace.composition.artifacts": - return "informational"; - default: - return "informational"; - } - } - - public getTitle(artifactType:string, selectedComponent:Component):string { - switch (artifactType) { - case "interface": - return "Lifecycle Management"; - case "api": - return "API Artifacts"; - case "deployment": - return "Deployment Artifacts"; - case "informational": - return "Informational Artifacts"; - default: - if (!selectedComponent) { - return ""; - } else { - return this.$filter("resourceName")(selectedComponent.name) + ' Artifacts'; - } - } - } - - public setArtifactType = (artifact:ArtifactModel, artifactType:string):void => { - switch (artifactType) { - case "api": - artifact.artifactGroupType = ArtifactGroupType.SERVICE_API; - break; - case "deployment": - artifact.artifactGroupType = ArtifactGroupType.DEPLOYMENT; - break; - default: - artifact.artifactGroupType = ArtifactGroupType.INFORMATION; - break; - } - }; - - public isLicenseType = (artifactType:string):boolean => { - let isLicense:boolean = false; - - if (ArtifactType.VENDOR_LICENSE === artifactType || ArtifactType.VF_LICENSE === artifactType) { - isLicense = true; - } - - return isLicense; - }; - - public removeArtifact = (artifact:ArtifactModel, artifactsArr:Array):void => { - - if (!artifact.mandatory && (ArtifactGroupType.INFORMATION == artifact.artifactGroupType || - 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:IArtifactResourceFormViewModelScope) { - let newArtifact = new 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/src/app/utils/change-lifecycle-state-handler.ts b/catalog-ui/src/app/utils/change-lifecycle-state-handler.ts index 54497ba187..6a37864fe1 100644 --- a/catalog-ui/src/app/utils/change-lifecycle-state-handler.ts +++ b/catalog-ui/src/app/utils/change-lifecycle-state-handler.ts @@ -17,18 +17,16 @@ * limitations under the License. * ============LICENSE_END========================================================= */ - -import {ComponentFactory} from "./component-factory"; -import {Component, Service,IAppMenu, IAppConfigurtaion} from "../models"; -import {IEmailModalModel, IEmailModalModel_Email, IEmailModalModel_Data} from "../view-models/modals/email-modal/email-modal-view-model"; -import {AsdcComment} from "../models/comments"; -import {ModalsHandler} from "./modals-handler"; -import {ServiceServiceNg2} from "../ng2/services/component-services/service.service"; -import {EventBusService} from "../ng2/services/event-bus.service"; - -/** - * Created by obarda on 2/11/2016. - */ +import { ServiceServiceNg2 } from 'app/ng2/services/component-services/service.service'; +import { EventBusService } from 'app/ng2/services/event-bus.service'; +import { EVENTS, ValidationUtils } from 'app/utils'; +import { SdcUiCommon, SdcUiComponents, SdcUiServices } from 'onap-ui-angular'; +import { Component, IAppConfigurtaion, IAppMenu, Service } from '../models'; +import { AsdcComment } from '../models/comments'; +import { CommentModalComponent } from '../ng2/components/modals/comment-modal/comment-modal.component'; +import { EventListenerService } from '../services/event-listener-service'; +import { ComponentFactory } from './component-factory'; +import { ModalsHandler } from './modals-handler'; export class ChangeLifecycleStateHandler { @@ -39,167 +37,130 @@ export class ChangeLifecycleStateHandler { '$filter', 'ModalsHandler', 'ServiceServiceNg2', - 'EventBusService' + 'EventBusService', + 'ModalServiceSdcUI', + 'ValidationUtils', + 'EventListenerService' ]; - constructor(private sdcConfig:IAppConfigurtaion, - private sdcMenu:IAppMenu, - private ComponentFactory:ComponentFactory, - private $filter:ng.IFilterService, - private ModalsHandler:ModalsHandler, - private ServiceServiceNg2:ServiceServiceNg2, - private eventBusService:EventBusService) { - + constructor(private sdcConfig: IAppConfigurtaion, + private sdcMenu: IAppMenu, + private componentFactory: ComponentFactory, + private $filter: ng.IFilterService, + private modalsHandler: ModalsHandler, + private serviceServiceNg2: ServiceServiceNg2, + private eventBusService: EventBusService, + private modalService: SdcUiServices.ModalService, + private validationUtils: ValidationUtils, + private eventListenerService: EventListenerService) { } - private actualChangeLifecycleState = (component:Component, data:any, scope:any, onSuccessCallback?:Function, onErrorCallback?:Function):void => { + public changeLifecycleState = (component: Component, data: any, scope: any, onSuccessCallback?: Function, onErrorCallback?: Function) => { + if (data.conformanceLevelModal) { + this.validateConformanceLevel(component, data, scope, onSuccessCallback, onErrorCallback); + } else { + this.actualChangeLifecycleState(component, data, scope, onSuccessCallback, onErrorCallback); + } + } - let self = this; + private actualChangeLifecycleState = (component: Component, data: any, scope: any, onSuccessCallback?: Function, onErrorCallback?: Function) => { + const self = this; - let getContacts = (component: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:Component):void => { - //scope.isLoading = false; - console.info(component.componentType.toLowerCase + ' change state ', newComponent); + const onSuccess = (newComponent: Component) => { if (onSuccessCallback) { - onSuccessCallback(self.ComponentFactory.createComponent(newComponent), data.url); + onSuccessCallback(self.componentFactory.createComponent(newComponent), data.url); + if (data.url === 'distribution/PROD/activate') { + this.eventListenerService.notifyObservers(EVENTS.ON_DISTRIBUTION_SUCCESS); + } } }; - let onError = (error):void => { + const onError = (error) => { scope.isLoading = false; - console.info('Failed to changeLifecycleState to ', data.url); if (onErrorCallback) { onErrorCallback(error); } }; - let comment:AsdcComment = new AsdcComment(); + const comment: AsdcComment = new AsdcComment(); if (data.alertModal) { // Show alert dialog if defined in menu.json - //------------------------------------------------- - let onOk = (confirmationText):void => { + const onOk: Function = (confirmationText) => { 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); + const modalTitle = this.sdcMenu.alertMessages[data.alertModal].title; + const modalMessage = this.sdcMenu.alertMessages[data.alertModal].message.format([component.componentType.toLowerCase()]); + const modalButton = { + testId: 'OK', + text: this.sdcMenu.alertMessages.okButton, + type: SdcUiCommon.ButtonType.warning, + callback: onOk, + closeModal: true + } as SdcUiComponents.ModalButtonComponent; + this.modalService.openWarningModal(modalTitle, modalMessage, 'alert-modal', [modalButton]); } else if (data.confirmationModal) { // Show confirmation dialog if defined in menu.json - //------------------------------------------------- - let onOk = (confirmationText):void => { - comment.userRemarks = confirmationText; - - if (data.url === "lifecycleState/CHECKIN") { - this.eventBusService.notify("CHECK_IN").subscribe(() => { + let commentModalInstance: SdcUiComponents.ModalComponent; + const onOk = () => { + const confirmationText: string = commentModalInstance.innerModalContent.instance.comment.text; + commentModalInstance.closeModal(); + comment.userRemarks = this.validationUtils.stripAndSanitize(confirmationText); + + if (data.url === 'lifecycleState/CHECKIN') { + this.eventBusService.notify('CHECK_IN').subscribe(() => { scope.isLoading = true; component.changeLifecycleState(data.url, comment).then(onSuccess, onError); }); - } - else { + } else { 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 (data.url === "lifecycleState/certificationRequest") { - this.eventBusService.notify("SUBMIT_FOR_TESTING").subscribe(() => { - if (resource) { - onSuccess(resource); - } else { - onError("Error changing life cycle state"); - } - }); - } - else { - if (resource) { - onSuccess(resource); - } else { - onError("Error changing life cycle state"); - } - } - }; - - let onCancel = ():void => { - scope.isLoading = false; - }; - - let emailModel:IEmailModalModel = {}; - emailModel.email = {}; - emailModel.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); - + const modalTitle = this.sdcMenu.confirmationMessages[data.confirmationModal].title; + const modalMessage = this.sdcMenu.confirmationMessages[data.confirmationModal].message.format([component.componentType.toLowerCase()]); + const modalConfig = { + size: 'md', + title: modalTitle, + type: SdcUiCommon.ModalType.custom, + testId: 'confirm-modal', + buttons: [ + { id: 'OK', text: 'OK', callback: onOk, closeModal: false, testId: 'OK' }, + { id: 'cancel', text: 'Cancel', size: 'x-small', type: 'secondary', closeModal: true, testId: 'Cancel' } + ] as SdcUiCommon.IModalButtonComponent[] + } as SdcUiCommon.IModalConfig; + commentModalInstance = this.modalService.openCustomModal(modalConfig, CommentModalComponent, { message: modalMessage }); + commentModalInstance.innerModalContent.instance.onValidationChange.subscribe((isValid) => { + commentModalInstance.getButtonById('OK').disabled = !isValid; + }); } else { // Submit to server only (no modal is shown). scope.isLoading = true; component.changeLifecycleState(data.url, comment).then(onSuccess, onError); } - - } - - public changeLifecycleState = (component:Component, data:any, scope:any, onSuccessCallback?:Function, onErrorCallback?:Function):void => { - - if (data.conformanceLevelModal) { - this.validateConformanceLevel(component, data, scope, onSuccessCallback, onErrorCallback); - } else { - this.actualChangeLifecycleState(component, data, scope, onSuccessCallback, onErrorCallback); - } } - private validateConformanceLevel = (component:Component, data:any, scope:any, onSuccessCallback?:Function, onErrorCallback?:Function):void => { + private validateConformanceLevel = (component: Component, data: any, scope: any, onSuccessCallback?: Function, onErrorCallback?: Function) => { // Validate conformance level if defined in menu.json - //------------------------------------------------- - this.ServiceServiceNg2.validateConformanceLevel(component).subscribe((res:boolean) => { + this.serviceServiceNg2.validateConformanceLevel(component as Service).subscribe((res: boolean) => { if (res === true) { - //conformance level is ok - continue + // Conformance level is ok - continue this.actualChangeLifecycleState(component, data, scope, onSuccessCallback, onErrorCallback); - } else { - //show warning modal - this.ModalsHandler.openConformanceLevelModal() - .then(() => { - //continue distribute - this.actualChangeLifecycleState(component, data, scope, onSuccessCallback, onErrorCallback); - - }).catch(() => { - //reject distribution - this.actualChangeLifecycleState(component, data.conformanceLevelModal, scope, onSuccessCallback, onErrorCallback); - }); + // Show warning modal + const onContinue: Function = () => { + this.actualChangeLifecycleState(component, data, scope, onSuccessCallback, onErrorCallback); + }; + const reject: Function = () => { + this.actualChangeLifecycleState(component, data.conformanceLevelModal, scope, onSuccessCallback, onErrorCallback); + }; + const continueButton = {testId: 'Continue', text: 'Continue', type: SdcUiCommon.ButtonType.primary, callback: onContinue, closeModal: true} as SdcUiComponents.ModalButtonComponent; + const rejectButton = {testId: 'Reject', text: 'Reject', type: SdcUiCommon.ButtonType.secondary, callback: reject, closeModal: true} as SdcUiComponents.ModalButtonComponent; + this.modalService.openInfoModal(this.$filter('translate')('CONFORMANCE_LEVEL_MODAL_TITLE'), + this.$filter('translate')('CONFORMANCE_LEVEL_MODAL_TEXT'), 'conformance-modal', [continueButton, rejectButton]); } }); } diff --git a/catalog-ui/src/app/utils/common-utils.ts b/catalog-ui/src/app/utils/common-utils.ts index 99f7c49a29..eadb92bd4f 100644 --- a/catalog-ui/src/app/utils/common-utils.ts +++ b/catalog-ui/src/app/utils/common-utils.ts @@ -19,11 +19,12 @@ */ import * as _ from "lodash"; -import {Module, AttributeModel, ResourceInstance, PropertyModel, InterfaceModel, OperationModel} from "../models"; +import {Module, AttributeModel, ResourceInstance, PropertyModel, InputFEModel, OperationModel} from "../models"; import {ComponentInstanceFactory} from "./component-instance-factory"; import {InputBEModel, PropertyBEModel, RelationshipModel} from "app/models"; import { PolicyInstance } from "app/models/graph/zones/policy-instance"; import { GroupInstance } from "../models/graph/zones/group-instance"; +import { InterfaceModel } from "../models/operation"; export class CommonUtils { @@ -167,7 +168,7 @@ export class CommonUtils { }); } - + static initInterfaceOperations(interfaces: Array): Array { return _.reduce(interfaces, (acc, interf: InterfaceModel) => { @@ -194,5 +195,6 @@ export class CommonUtils { }, []); } + } diff --git a/catalog-ui/src/app/utils/component-factory.ts b/catalog-ui/src/app/utils/component-factory.ts index 2b134bd2e7..889f6fb43b 100644 --- a/catalog-ui/src/app/utils/component-factory.ts +++ b/catalog-ui/src/app/utils/component-factory.ts @@ -21,7 +21,8 @@ 'use strict'; import * as _ from "lodash"; import {DEFAULT_ICON, ResourceType, ComponentType} from "./constants"; -import {ServiceService, CacheService, ResourceService} from "app/services"; +import {ServiceService, ResourceService} from "app/services"; +import {CacheService} from "app/services-ng2"; import {IMainCategory, ISubCategory, ICsarComponent, Component, Resource, Service} from "app/models"; import {ComponentMetadata} from "../models/component-metadata"; import {ComponentServiceNg2} from "../ng2/services/component-services/component.service"; @@ -71,23 +72,23 @@ export class ComponentFactory { return newResource; }; - public updateComponentFromCsar = (csarComponent:Resource, oldComponent:Resource):Component => { - _.pull(oldComponent.tags, oldComponent.name); - if (!oldComponent.isAlreadyCertified()) { + public updateComponentFromCsar = (csarComponent:Resource, oldComponent: Resource): Component => { + _.pull(oldComponent.tags, oldComponent.name); + if (!oldComponent.isAlreadyCertified()) { oldComponent.name = csarComponent.name; oldComponent.categories = csarComponent.categories; oldComponent.selectedCategory = csarComponent.selectedCategory; } - oldComponent.vendorName = csarComponent.vendorName; - oldComponent.vendorRelease = csarComponent.vendorRelease; - oldComponent.csarUUID = csarComponent.csarUUID; - oldComponent.csarPackageType = csarComponent.csarPackageType; - oldComponent.csarVersion = csarComponent.csarVersion; - oldComponent.packageId = csarComponent.packageId; - oldComponent.description = csarComponent.description; - oldComponent.filterTerm = oldComponent.name + ' ' + oldComponent.description + ' ' + oldComponent.vendorName + ' ' + oldComponent.csarVersion - return oldComponent; - }; + oldComponent.vendorName = csarComponent.vendorName; + oldComponent.vendorRelease = csarComponent.vendorRelease; + oldComponent.csarUUID = csarComponent.csarUUID; + oldComponent.csarPackageType = csarComponent.csarPackageType; + oldComponent.csarVersion = csarComponent.csarVersion; + oldComponent.packageId = csarComponent.packageId; + oldComponent.description = csarComponent.description; + oldComponent.filterTerm = oldComponent.name + ' ' + oldComponent.description + ' ' + oldComponent.vendorName + ' ' + oldComponent.csarVersion; + return oldComponent; + } public createFromCsarComponent = (csar:ICsarComponent):Component => { let newResource:Resource = this.createEmptyComponent(ComponentType.RESOURCE); @@ -126,7 +127,7 @@ export class ComponentFactory { } // 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; @@ -136,7 +137,8 @@ export class ComponentFactory { newResource.packageId = csar.packageId; newResource.description = csar.description; newResource.resourceType = csar.resourceType; - newResource.filterTerm = newResource.name + ' ' + newResource.description + ' ' + newResource.vendorName + ' ' + newResource.csarVersion + newResource.selectedCategory = selectedCategory && selectedSubCategory ? selectedCategory.name + "_#_" + selectedSubCategory.name : ''; + newResource.filterTerm = newResource.name + ' ' + newResource.description + ' ' + newResource.vendorName + ' ' + newResource.csarVersion; return newResource; }; @@ -183,7 +185,7 @@ export class ComponentFactory { let deferred = this.$q.defer(); let component = this.createEmptyComponent(componentType); component.setUniqueId(componentId); - this.ComponentServiceNg2.getComponentMetadata(component).subscribe((response:ComponentGenericResponse) => { + this.ComponentServiceNg2.getComponentMetadata(component.uniqueId, component.componentType).subscribe((response:ComponentGenericResponse) => { component.setComponentMetadata(response.metadata); deferred.resolve(component); }); diff --git a/catalog-ui/src/app/utils/component-instance-factory.ts b/catalog-ui/src/app/utils/component-instance-factory.ts index 25916cc055..03abd96a77 100644 --- a/catalog-ui/src/app/utils/component-instance-factory.ts +++ b/catalog-ui/src/app/utils/component-instance-factory.ts @@ -7,9 +7,9 @@ * 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. @@ -21,14 +21,14 @@ * Created by obarda on 3/7/2016. */ 'use strict'; -import {ComponentInstance, ServiceInstance, ResourceInstance, Component, ServiceProxyInstance} from "../models"; -import {ComponentType} from "app/utils"; -import {LeftPaletteComponent} from "../models/components/displayComponent"; +import { ComponentType } from 'app/utils'; +import { Component, ComponentInstance, ResourceInstance, ServiceInstance, ServiceProxyInstance } from '../models'; +import { LeftPaletteComponent } from '../models/components/displayComponent'; export class ComponentInstanceFactory { - static createComponentInstance(componentInstance:ComponentInstance):ComponentInstance { - let newComponentInstance:ComponentInstance; + static createComponentInstance(componentInstance: ComponentInstance): ComponentInstance { + let newComponentInstance: ComponentInstance; switch (componentInstance.originType) { case ComponentType.SERVICE: newComponentInstance = new ServiceInstance(componentInstance); @@ -41,10 +41,10 @@ export class ComponentInstanceFactory { break; } return newComponentInstance; - }; + } - public createEmptyComponentInstance = (componentInstanceType?:string):ComponentInstance => { - let newComponentInstance:ComponentInstance; + static createEmptyComponentInstance = (componentInstanceType?: string): ComponentInstance => { + let newComponentInstance: ComponentInstance; switch (componentInstanceType) { case ComponentType.SERVICE: newComponentInstance = new ServiceInstance(); @@ -57,25 +57,32 @@ export class ComponentInstanceFactory { break; } return newComponentInstance; - }; + } - public createComponentInstanceFromComponent = (component:LeftPaletteComponent):ComponentInstance => { - let newComponentInstance:ComponentInstance = this.createEmptyComponentInstance(component.componentType); + static createComponentInstanceFromComponent = (component: LeftPaletteComponent): ComponentInstance => { + const newComponentInstance: ComponentInstance = ComponentInstanceFactory.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(); - if(component.getComponentSubType() === ComponentType.SERVICE){ - newComponentInstance.originType = ComponentType.SERVICE_PROXY - } - //new component instance -> req. & cap. are added on successful instance creation + newComponentInstance.originType = getOriginType(component); newComponentInstance.requirements = component.requirements; newComponentInstance.capabilities = component.capabilities; newComponentInstance.icon = component.icon; newComponentInstance.componentUid = component.uniqueId; return newComponentInstance; - }; + function getOriginType(component: LeftPaletteComponent): string { + if (component.componentSubType) { + return component.componentSubType; + } else { + if (component.componentType === ComponentType.SERVICE) { + return ComponentType.SERVICE_PROXY; + } else { + return component.resourceType; + } + } + } + } } diff --git a/catalog-ui/src/app/utils/constants.ts b/catalog-ui/src/app/utils/constants.ts index 9d3bf104ee..e82322e0de 100644 --- a/catalog-ui/src/app/utils/constants.ts +++ b/catalog-ui/src/app/utils/constants.ts @@ -43,8 +43,20 @@ export class ComponentType { export class ServerTypeUrl { static RESOURCES = 'resources/'; static SERVICES = 'services/'; + + public static toServerTypeUrl(componentType: ComponentType) : string { + if (componentType == ComponentType.SERVICE) { + return ServerTypeUrl.SERVICES.slice(0,-1); + } else if (componentType == ComponentType.RESOURCE) { + return ServerTypeUrl.RESOURCES.slice(0,-1); + } else { + return undefined; + } + } } + + export class ResourceType { static VF = 'VF'; static VL = 'VL'; @@ -57,6 +69,11 @@ export class ResourceType { static CR = 'CR'; } +export class SdcElementType { + static GROUP = 'GROUP'; + static POLICY = 'POLICY'; + static SERVICE_PROXY = 'ServiceProxy' +} export class ComponentState { static CERTIFICATION_IN_PROGRESS = 'CERTIFICATION_IN_PROGRESS'; static CERTIFIED = 'CERTIFIED'; @@ -76,9 +93,15 @@ export class ArtifactGroupType { static DEPLOYMENT = "DEPLOYMENT"; static INFORMATION = "INFORMATIONAL"; static SERVICE_API = "SERVICE_API"; + static TOSCA = "TOSCA"; } export class ArtifactType { + + static DEPLOYMENT = "DEPLOYMENT"; + static INFORMATION = "INFORMATIONAL"; + static SERVICE_API = "SERVICE_API"; + static HEAT_ENV = "HEAT_ENV"; static HEAT = "HEAT"; static HEAT_VOL = "HEAT_VOL"; static HEAT_NET = "HEAT_NET"; @@ -202,6 +225,7 @@ export class ServerErrors { static ERROR_TITLE = 'Error'; static DEFAULT_ERROR = 'Error getting response from server'; static MESSAGE_ERROR = 'Wrong error format from server'; + static DOWNLOAD_ERROR = 'Download error'; } export class GraphColors { @@ -255,6 +279,8 @@ export class States { 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_INFORMATION_ARTIFACTS = 'workspace.information_artifacts'; public static WORKSPACE_TOSCA_ARTIFACTS = 'workspace.tosca_artifacts'; @@ -287,6 +313,7 @@ export class EVENTS { static SHOW_LOADER_EVENT = "showLoaderEvent"; static HIDE_LOADER_EVENT = "hideLoaderEvent"; static UPDATE_PANEL = 'updatePanel'; + static ON_DISTRIBUTION_SUCCESS = 'onDistributionSuccess'; } @@ -312,6 +339,7 @@ export class GRAPH_EVENTS { static ON_PALETTE_COMPONENT_HOVER_OUT = 'onPaletteComponentHoverOut'; static ON_PALETTE_COMPONENT_DRAG_START = 'onPaletteComponentDragStart'; static ON_PALETTE_COMPONENT_DRAG_ACTION = 'onPaletteComponentDragAction'; + static ON_PALETTE_COMPONENT_DROP = 'onPaletteComponentDrop'; static ON_PALETTE_COMPONENT_SHOW_POPUP_PANEL = 'onPaletteComponentShowPopupPanel'; static ON_PALETTE_COMPONENT_HIDE_POPUP_PANEL = 'onPaletteComponentHidePopupPanel'; static ON_COMPONENT_INSTANCE_NAME_CHANGED = 'onComponentInstanceNameChanged'; @@ -329,6 +357,7 @@ export class GRAPH_EVENTS { static ON_CANVAS_TAG_END = 'onCanvasTagEnd'; static ON_POLICY_INSTANCE_UPDATE = 'onPolicyInstanceUpdate'; static ON_GROUP_INSTANCE_UPDATE = 'onGroupInstanceUpdate'; + static ON_SERVICE_PATH_CREATED = 'onServicePathCreated'; } export class DEPENDENCY_EVENTS { @@ -349,6 +378,7 @@ export class COMPONENT_FIELDS { static COMPONENT_INFORMATIONAL_ARTIFACTS = "artifacts"; static COMPONENT_PROPERTIES = "properties"; static COMPONENT_CAPABILITIES = "capabilities"; + static COMPONENT_CAPABILITIES_PROPERTIES = "instanceCapabiltyProperties"; static COMPONENT_REQUIREMENTS = "requirements"; static COMPONENT_TOSCA_ARTIFACTS = "toscaArtifacts"; static COMPONENT_POLICIES = "policies"; @@ -357,6 +387,8 @@ export class COMPONENT_FIELDS { static COMPONENT_INSTANCES_INTERFACES = "componentInstancesInterfaces"; static COMPONENT_NON_EXCLUDED_GROUPS = "nonExcludedGroups"; static COMPONENT_NON_EXCLUDED_POLICIES = "nonExcludedPolicies"; + static FORWARDING_PATHS = "forwardingPaths"; + static SERVICE_API_ARTIFACT = "serviceApiArtifacts"; } export class SERVICE_FIELDS { diff --git a/catalog-ui/src/app/utils/menu-handler.ts b/catalog-ui/src/app/utils/menu-handler.ts index eaef63fcc7..e17012a45e 100644 --- a/catalog-ui/src/app/utils/menu-handler.ts +++ b/catalog-ui/src/app/utils/menu-handler.ts @@ -40,7 +40,6 @@ export class MenuItem { alertModal:string; conformanceLevelModal: boolean; // Call validateConformanceLevel API and shows conformanceLevelModal if necessary, then continue with action or invokes another action 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. diff --git a/catalog-ui/src/app/utils/modals-handler.ts b/catalog-ui/src/app/utils/modals-handler.ts index 903175f199..342f03f290 100644 --- a/catalog-ui/src/app/utils/modals-handler.ts +++ b/catalog-ui/src/app/utils/modals-handler.ts @@ -7,9 +7,9 @@ * 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. @@ -18,25 +18,13 @@ * ============LICENSE_END========================================================= */ -import {PropertyModel, Component, ArtifactModel, Distribution, InputModel, DisplayModule, InputPropertyBase} from "../models"; -import {IEmailModalModel} from "../view-models/modals/email-modal/email-modal-view-model"; -import {IClientMessageModalModel} from "../view-models/modals/message-modal/message-client-modal/client-message-modal-view-model"; -import {IServerMessageModalModel} from "../view-models/modals/message-modal/message-server-modal/server-message-modal-view-model"; -import {IConfirmationModalModel} from "../view-models/modals/confirmation-modal/confirmation-modal-view-model"; -import {ModalType} from "./constants"; -import {AttributeModel} from "../models/attributes"; +import { Component, DisplayModule , PropertyModel } from '../models'; +import { ComponentMetadata } from '../models/component-metadata'; export interface IModalsHandler { - - openDistributionStatusModal (distribution:Distribution, status:string, component:Component):ng.IPromise; - openConfirmationModal (title:string, message:string, showComment:boolean, size?:string):ng.IPromise; - openAlertModal (title:string, message:string, size?:string):ng.IPromise; - openEmailModal(emailModel:IEmailModalModel):ng.IPromise; - openServerMessageModal(data:IServerMessageModalModel):ng.IPromise; - openClientMessageModal(data:IClientMessageModalModel):ng.IPromise; - openArtifactModal(artifact:ArtifactModel, component:Component):ng.IPromise; - openEditPropertyModal(property:PropertyModel, component:Component, filteredProperties:Array, isPropertyOwnValue:boolean, propertyOwnerType:string, propertyOwnerId:string):ng.IPromise; + openEditPropertyModal(property: PropertyModel, component: Component, filteredProperties: PropertyModel[], isPropertyOwnValue: boolean, + propertyOwnerType: string, propertyOwnerId: string): ng.IPromise; } export class ModalsHandler implements IModalsHandler { @@ -46,230 +34,27 @@ export class ModalsHandler implements IModalsHandler { '$q' ]; - constructor(private $uibModal:ng.ui.bootstrap.IModalService, - private $q:ng.IQService) { + constructor(private $uibModal: ng.ui.bootstrap.IModalService, + private $q: ng.IQService) { } - - - - openDistributionStatusModal = (distribution:Distribution, status:string, component:Component):ng.IPromise => { - let deferred = this.$q.defer(); - let modalOptions:ng.ui.bootstrap.IModalSettings = { - templateUrl: '../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, - 'component': component - }; - } - } - }; - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); - deferred.resolve(modalInstance.result); - return deferred.promise; - }; - - - openAlertModal = (title:string, message:string, size?:string):ng.IPromise => { - return this.openConfirmationModalBase(title, message, false, ModalType.ALERT, size); - }; - - openConfirmationModal = (title:string, message:string, showComment:boolean, size?:string):ng.IPromise => { - return this.openConfirmationModalBase(title, message, showComment, ModalType.STANDARD, size); - }; - - private openConfirmationModalBase = (title:string, message:string, showComment:boolean, type:ModalType, size?:string):ng.IPromise => { - let deferred = this.$q.defer(); - let modalOptions:ng.ui.bootstrap.IModalSettings = { - templateUrl: '../view-models/modals/confirmation-modal/confirmation-modal-view.html', - controller: 'Sdc.ViewModels.ConfirmationModalViewModel', - size: size ? size : 'sdc-sm', - backdrop: 'static', - resolve: { - confirmationModalModel: ():IConfirmationModalModel => { - let model:IConfirmationModalModel = { - title: title, - message: message, - showComment: showComment, - type: type - }; - return model; - } - } - }; - - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); - deferred.resolve(modalInstance.result); - return deferred.promise; - }; - - openEmailModal = (emailModel:IEmailModalModel):ng.IPromise => { - - let deferred = this.$q.defer(); - let modalOptions:ng.ui.bootstrap.IModalSettings = { - templateUrl: '../view-models/modals/email-modal/email-modal-view.html', - controller: 'Sdc.ViewModels.EmailModalViewModel', - size: 'sdc-sm', - backdrop: 'static', - resolve: { - emailModalModel: ():IEmailModalModel => { - return emailModel; - } - } - }; - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); - deferred.resolve(modalInstance.result); - return deferred.promise; - - }; - - openServerMessageModal = (data:IServerMessageModalModel):ng.IPromise => { - let deferred = this.$q.defer(); - let modalOptions:ng.ui.bootstrap.IModalSettings = { - templateUrl: '../view-models/modals/message-modal/message-server-modal/server-message-modal-view.html', - controller: 'Sdc.ViewModels.ServerMessageModalViewModel', - size: 'sdc-sm', - backdrop: 'static', - resolve: { - serverMessageModalModel: ():IServerMessageModalModel => { - return data; - } - } - }; - - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); - deferred.resolve(modalInstance.result); - return deferred.promise; - }; - - openClientMessageModal = (data:IClientMessageModalModel):ng.IPromise => { - let deferred = this.$q.defer(); - let modalOptions:ng.ui.bootstrap.IModalSettings = { - templateUrl: '../view-models/modals/message-modal/message-client-modal/client-message-modal-view.html', - controller: 'Sdc.ViewModels.ClientMessageModalViewModel', - size: 'sdc-sm', - backdrop: 'static', - resolve: { - clientMessageModalModel: ():IClientMessageModalModel => { - return data; - } - } - }; - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); - deferred.resolve(modalInstance); - return deferred.promise; - }; - - openOnboadrdingModal = (okButtonText:string, currentCsarUUID?:string, currentCsarVersion?:string):ng.IPromise => { - let deferred = this.$q.defer(); - let modalOptions:ng.ui.bootstrap.IModalSettings = { - templateUrl: '../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; - }, - currentCsarVersion: ():string=> { - return currentCsarVersion || null; - } - } - }; - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); - deferred.resolve(modalInstance.result); - return deferred.promise; - }; - - openUpdateIconModal = (component: Component):ng.IPromise => { - let deferred = this.$q.defer(); - let modalOptions:ng.ui.bootstrap.IModalSettings = { + openUpdateIconModal = (component: Component): ng.IPromise => { + const deferred = this.$q.defer(); + const modalOptions: ng.ui.bootstrap.IModalSettings = { templateUrl: '../view-models/modals/icons-modal/icons-modal-view.html', controller: 'Sdc.ViewModels.IconsModalViewModel', size: 'sdc-auto', backdrop: 'static', resolve: { - component: ():Component => { - return component; - } - } - }; - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); - deferred.resolve(modalInstance.result); - return deferred.promise; - }; - - openEditEnvParametersModal = (artifactResource:ArtifactModel, component?:Component):ng.IPromise => { - let deferred = this.$q.defer(); - let modalOptions:ng.ui.bootstrap.IModalSettings = { - templateUrl: '../view-models/forms/env-parameters-form/env-parameters-form.html', - controller: 'Sdc.ViewModels.EnvParametersFormViewModel', - size: 'sdc-xl', - backdrop: 'static', - resolve: { - artifact: ():ArtifactModel => { - return artifactResource; - }, - component: ():Component => { + component: (): Component => { return component; } } }; - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); + const modalInstance: ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); deferred.resolve(modalInstance.result); return deferred.promise; - }; - - openEditInputValueModal = (input:InputModel):ng.IPromise => { - let deferred = this.$q.defer(); - let modalOptions:ng.ui.bootstrap.IModalSettings = { - templateUrl: '../view-models/forms/input-form/input-form-view.html', - controller: 'Sdc.ViewModels.InputFormViewModel', - size: 'sdc-md', - backdrop: 'static', - resolve: { - input: ():InputModel => { - return input; - } - } - }; - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); - deferred.resolve(modalInstance.result); - return deferred.promise; - }; - - openArtifactModal = (artifact:ArtifactModel, component:Component):ng.IPromise => { - let deferred = this.$q.defer(); - let modalOptions:ng.ui.bootstrap.IModalSettings = { - templateUrl: '../view-models/forms/artifact-form/artifact-form-view.html', - controller: 'Sdc.ViewModels.ArtifactResourceFormViewModel', - size: 'sdc-md', - backdrop: 'static', - keyboard: false, - resolve: { - artifact: ():ArtifactModel => { - return artifact; - }, - component: ():Component => { - return component; - } - } - }; - - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); - deferred.resolve(modalInstance.result); - return deferred.promise; - }; - + } /** * @@ -281,158 +66,113 @@ export class ModalsHandler implements IModalsHandler { * @param isPropertyValueOwner - boolean telling if the component is eligible of editing the property * @returns {IPromise} - Promise telling if the modal has opened or not */ - openEditPropertyModal = (property:PropertyModel, component:Component, filteredProperties:Array, isPropertyValueOwner:boolean, propertyOwnerType:string, propertyOwnerId:string):ng.IPromise => { - let deferred = this.$q.defer(); + openEditPropertyModal = (property: PropertyModel, component: Component | ComponentMetadata, filteredProperties: PropertyModel[], + isPropertyValueOwner: boolean, propertyOwnerType: string, propertyOwnerId: string): ng.IPromise => { + const deferred = this.$q.defer(); - let modalOptions:ng.ui.bootstrap.IModalSettings = { + const modalOptions: ng.ui.bootstrap.IModalSettings = { templateUrl: '../view-models/forms/property-forms/component-property-form/property-form-view.html', controller: 'Sdc.ViewModels.PropertyFormViewModel', size: 'sdc-l', backdrop: 'static', keyboard: false, resolve: { - property: ():PropertyModel => { + property: (): PropertyModel => { return property; }, - component: ():Component => { - return component; + component: (): Component => { + return component as Component; }, - filteredProperties: ():Array => { + filteredProperties: (): PropertyModel[] => { return filteredProperties; }, - isPropertyValueOwner: ():boolean => { + isPropertyValueOwner: (): boolean => { return isPropertyValueOwner; }, - propertyOwnerType: ():string => { + propertyOwnerType: (): string => { return propertyOwnerType; }, - propertyOwnerId: ():string => { + propertyOwnerId: (): string => { return propertyOwnerId; } } }; - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); + const modalInstance: ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); deferred.resolve(modalInstance.result); return deferred.promise; - }; - + } - openEditModulePropertyModal = (property:PropertyModel, component:Component, selectedModule:DisplayModule, filteredProperties:Array):ng.IPromise => { - let deferred = this.$q.defer(); + /** + * + * This function openes up the edit property modal + * + * @param property - the property to edit + * @param filteredProperties - the filtered properties list to scroll between in the edit modal + * @param isPropertyValueOwner - boolean telling if the component is eligible of editing the property + * @returns {IPromise} - Promise telling if the modal has opened or not + */ + newOpenEditPropertyModal = (property: PropertyModel, filteredProperties: PropertyModel[], isPropertyValueOwner: boolean, propertyOwnerType: string, propertyOwnerId: string): ng.IPromise => { + const deferred = this.$q.defer(); - let modalOptions:ng.ui.bootstrap.IModalSettings = { - templateUrl: '../view-models/forms/property-forms/base-property-form/property-form-base-view.html', - controller: 'Sdc.ViewModels.ModulePropertyView', + const modalOptions: ng.ui.bootstrap.IModalSettings = { + templateUrl: '../view-models/forms/property-forms/component-property-form/property-form-view.html', + controller: 'Sdc.ViewModels.PropertyFormViewModel', size: 'sdc-l', backdrop: 'static', keyboard: false, resolve: { - originalProperty: ():PropertyModel => { + property: (): PropertyModel => { return property; }, - component: ():Component => { - return component; + filteredProperties: (): PropertyModel[] => { + return filteredProperties; }, - selectedModule: ():DisplayModule => { - return selectedModule; + isPropertyValueOwner: (): boolean => { + return isPropertyValueOwner; }, - filteredProperties: ():Array => { - return filteredProperties; + propertyOwnerType: (): string => { + return propertyOwnerType; + }, + propertyOwnerId: (): string => { + return propertyOwnerId; } } }; - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); + const modalInstance: ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); deferred.resolve(modalInstance.result); return deferred.promise; - }; + } - openSelectDataTypeModal = (property:PropertyModel, component:Component, filteredProperties:Array, propertiesMap:Array):ng.IPromise => { - let deferred = this.$q.defer(); + openEditModulePropertyModal = (property: PropertyModel, component: Component, selectedModule: DisplayModule, filteredProperties: PropertyModel[]): ng.IPromise => { + const deferred = this.$q.defer(); - let modalOptions:ng.ui.bootstrap.IModalSettings = { + const modalOptions: ng.ui.bootstrap.IModalSettings = { templateUrl: '../view-models/forms/property-forms/base-property-form/property-form-base-view.html', - controller: 'Sdc.ViewModels.SelectDataTypeViewModel', + controller: 'Sdc.ViewModels.ModulePropertyView', size: 'sdc-l', backdrop: 'static', keyboard: false, resolve: { - originalProperty: ():PropertyModel => { + originalProperty: (): PropertyModel => { return property; }, - component: ():Component => { - return component; - }, - filteredProperties: ():Array => { - return filteredProperties; + component: (): Component => { + return component as Component; }, - propertiesMap: ():Array=> { - return propertiesMap; - } - } - }; - - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); - deferred.resolve(modalInstance.result); - return deferred.promise; - }; - - public openEditAttributeModal = (attribute:AttributeModel, component: Component):void => { - - let modalOptions:ng.ui.bootstrap.IModalSettings = { - templateUrl: '../view-models/forms/attribute-form/attribute-form-view.html', - controller: 'Sdc.ViewModels.AttributeFormViewModel', - size: 'sdc-md', - backdrop: 'static', - keyboard: false, - resolve: { - attribute: ():AttributeModel => { - return attribute; + selectedModule: (): DisplayModule => { + return selectedModule; }, - component: ():Component => { - return component; - } - } - }; - this.$uibModal.open(modalOptions); - }; - - public openUpdateComponentInstanceNameModal = (currentComponent: Component):ng.IPromise => { - let deferred = this.$q.defer(); - - let modalOptions:ng.ui.bootstrap.IModalSettings = { - templateUrl: '../view-models/forms/resource-instance-name-form/resource-instance-name-view.html', - controller: 'Sdc.ViewModels.ResourceInstanceNameViewModel', - size: 'sdc-sm', - backdrop: 'static', - resolve: { - component: ():Component => { - return currentComponent; + filteredProperties: (): PropertyModel[] => { + return filteredProperties; } } }; - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); - deferred.resolve(modalInstance.result); - return deferred.promise; - }; - - public openConformanceLevelModal = ():ng.IPromise => { - let deferred = this.$q.defer(); - let modalOptions:ng.ui.bootstrap.IModalSettings = { - templateUrl: '../view-models/modals/conformance-level-modal/conformance-level-modal-view.html', - controller: 'Sdc.ViewModels.ConformanceLevelModalViewModel', - size: 'sdc-sm', - backdrop: 'static', - resolve: { - - } - }; - - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); + const modalInstance: ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); deferred.resolve(modalInstance.result); return deferred.promise; - }; + } } diff --git a/catalog-ui/src/app/utils/validation-utils.ts b/catalog-ui/src/app/utils/validation-utils.ts index cd90ba7752..b7e43f79ba 100644 --- a/catalog-ui/src/app/utils/validation-utils.ts +++ b/catalog-ui/src/app/utils/validation-utils.ts @@ -97,25 +97,25 @@ export class ValidationUtils { } }; - public getPropertyListPatterns():IMapRegex { + public static 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?)*$/ + 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 { + public static 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?)*$/ + 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 { + public static validateUniqueKeys(viewValue: string): boolean { if (!viewValue) { return true; //allow empty value } diff --git a/catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard-view-model.ts b/catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard-view-model.ts index c9ffe470f0..40a9e8fde1 100644 --- a/catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard-view-model.ts +++ b/catalog-ui/src/app/view-models/admin-dashboard/admin-dashboard-view-model.ts @@ -19,7 +19,7 @@ */ 'use strict'; -import {CacheService} from "app/services"; +import {CacheService} from "app/services-ng2"; import {IAppConfigurtaion} from "app/models"; interface IAdminDashboardViewModelScope extends ng.IScope { diff --git a/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view-model.ts b/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view-model.ts index c99f9e874d..bb4c44d8da 100644 --- a/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view-model.ts +++ b/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view-model.ts @@ -20,7 +20,8 @@ 'use strict'; import {ModalsHandler, ValidationUtils} from "app/utils"; -import {CacheService, ICategoryResource} from "app/services"; +import {ICategoryResource} from "app/services"; +import {CacheService} from "app/services-ng2"; import {IAppConfigurtaion} from "app/models"; import {ComponentType} from "../../../utils/constants"; @@ -138,58 +139,6 @@ export class CategoryManagementViewModel { }; - scope.deleteCategory = (category:ICategoryResource, subCategory:ICategoryResource):void => { - - let onOk = ():void => { - - scope.isLoading = true; - let type:string = scope.type; - - let onError = (response):void => { - scope.isLoading = false; - console.info('onFaild', response); - }; - - let onSuccess = (response:any):void => { - let arr:Array; - - if (!subCategory) { - arr = this.$scope[type + 'Categories']; - arr.splice(arr.indexOf(category), 1); - if (category === scope.selectedCategory) { - scope.selectedCategory = null; - scope.selectedSubCategory = null; - } - } else { - arr = category.subcategories; - arr.splice(arr.indexOf(subCategory), 1); - } - - scope.isLoading = false; - }; - - if (!subCategory) { - category.$delete({ - types: type + "s", - categoryId: category.uniqueId - } - , onSuccess, onError); - } else { - category.$deleteSubCategory({ - types: type + "s", - categoryId: category.uniqueId, - subCategoryId: subCategory.uniqueId, - } - , onSuccess, onError); - } - }; - let modelType:string = subCategory ? 'sub category' : 'category'; - let title:string = this.$filter('translate')("DELETE_CATEGORY_MODAL_HEADER", "{'modelType': '" + modelType + "' }"); - let message:string = this.$filter('translate')("DELETE_CATEGORY_MODAL_CATEGORY_NAME", "{'modelType': '" + modelType + "' }"); - - this.ModalsHandler.openConfirmationModal(title, message, false, 'sdc-xsm').then(onOk); - }; - this.$scope.serviceCategories = this.cacheService.get('serviceCategories'); this.$scope.resourceCategories = this.cacheService.get('resourceCategories'); } diff --git a/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view.html b/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view.html index d7ee87e2e7..30b71f28e2 100644 --- a/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view.html +++ b/catalog-ui/src/app/view-models/admin-dashboard/category-management/category-management-view.html @@ -36,9 +36,6 @@ data-ng-click="selectCategory(category)" data-tests-id="{{ type === SERVICE ? 'servicecategory' : 'resourcecategory' }}"> {{category.name}} - - -
    @@ -56,9 +53,6 @@ data-ng-click="selectSubCategory(subcategory)" data-tests-id="subcategory"> {{subcategory.name}} - - - diff --git a/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view-model.ts b/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view-model.ts index 45232b7a61..43ae75e048 100644 --- a/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view-model.ts +++ b/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view-model.ts @@ -20,55 +20,40 @@ 'use strict'; import * as _ from "lodash"; -import {ModalsHandler} from "app/utils"; -import {User, IUserProperties, IUser, IAppConfigurtaion} from "app/models"; -import {UserService} from "../../../ng2/services/user.service"; +import { User, IUserProperties, IUser, IAppConfigurtaion } from "app/models"; +import { UserService } from "../../../ng2/services/user.service"; +import { SdcUiCommon, SdcUiServices, SdcUiComponents } from "onap-ui-angular"; +import { AuthenticationService } from "app/ng2/services/authentication.service"; interface IUserManagementViewModelScope extends ng.IScope { - sdcConfig:IAppConfigurtaion; usersList:Array; isLoading:boolean; - isNewUser:boolean; sortBy:string; reverse:boolean; tableHeadersList:any; - roles:Array; - newUser:IUser; - currentUser:IUserProperties; - userIdValidationPattern:RegExp; - editForm:ng.IFormController; getAllUsers():void; - editUserRole(user:IUserProperties); sort(sortBy:string):void; - createUser():void; - deleteUser(userId:string):void; - onEditUserPressed(user:IUserProperties):void; - saveUserChanges(user:IUserProperties):void; getTitle(role:string):string; - clearForm():void; - } export class UserManagementViewModel { static '$inject' = [ '$scope', - 'sdcConfig', 'UserServiceNg2', - 'UserIdValidationPattern', + 'AuthenticationServiceNg2', '$filter', - 'ModalsHandler' + 'ModalServiceSdcUI' ]; constructor(private $scope:IUserManagementViewModelScope, - private sdcConfig:IAppConfigurtaion, private userService:UserService, - private UserIdValidationPattern:RegExp, + private authService:AuthenticationService, private $filter:ng.IFilterService, - private ModalsHandler:ModalsHandler) { + private modalService:SdcUiServices.ModalService) { - this.initScope(); + setTimeout(this.initScope, 1000); } @@ -89,13 +74,8 @@ export class UserManagementViewModel { this.userService.getAllUsers().subscribe(onSuccess, onError); }; - private updateUserFilterTerm = (user:IUserProperties):void => { - user.filterTerm = user.firstName + ' ' + user.lastName + ' ' + user.userId + ' ' + user.email + ' ' + user.role + ' ' + this.$filter('date')(user.lastLoginTime, "MM/dd/yyyy"); - }; - private initScope = ():void => { let self = this; - this.$scope.tableHeadersList = [{title: "First Name", property: 'firstName'}, { title: "Last Name", property: 'lastName' @@ -107,116 +87,18 @@ export class UserManagementViewModel { title: "Last Active", property: 'lastLoginTime' }]; - this.$scope.userIdValidationPattern = this.UserIdValidationPattern; this.$scope.sortBy = 'lastLoginTime'; this.$scope.reverse = false; - this.$scope.roles = this.sdcConfig.roles; - this.$scope.isNewUser = false; - this.$scope.currentUser = this.userService.getLoggedinUser(); this.getAllUsers(); - let userInfo:IUserProperties = {}; - this.$scope.newUser = new User(userInfo); - this.$scope.sort = (sortBy:string):void => {//default sort by descending last update. default for alphabetical = ascending - this.$scope.isNewUser = false; this.$scope.reverse = (this.$scope.sortBy === sortBy) ? ( !this.$scope.reverse) : this.$scope.reverse = false; this.$scope.sortBy = sortBy; }; - this.$scope.createUser = ():void => { - - let onError = (response) => { - this.$scope.isLoading = false; - console.info('onFaild', response); - }; - - let onSuccess = (response:IUserProperties) => { - this.$scope.newUser.userInfo.lastLoginTime = "0"; - this.$scope.newUser.userInfo.status = response.status; - this.updateUserFilterTerm(this.$scope.newUser.userInfo); - this.$scope.usersList.push(this.$scope.newUser.userInfo); - this.$scope.isNewUser = true; - this.$scope.sortBy = null; - this.$scope.reverse = true; - this.$scope.isLoading = false; - this.$scope.newUser = new User(null); - this.$scope.editForm.$setPristine(); - let _self = this; - setTimeout(function () { - _self.$scope.isNewUser = false; - }, 7000); - }; - this.userService.createUser({ - userId: this.$scope.newUser.userInfo.userId, - role: this.$scope.newUser.userInfo.role - }).subscribe(onSuccess, onError); - }; - - - this.$scope.onEditUserPressed = (user:IUserProperties):void => { - user.isInEditMode = true; - user.tempRole = user.role; - }; - - this.$scope.editUserRole = (user:IUserProperties):void => { - let roleBeforeUpdate:string = user.role; - user.role = user.tempRole; - - let onError = (response) => { - this.$scope.isLoading = false; - user.role = roleBeforeUpdate; - console.info('onFaild', response); - }; - let onSuccess = (response:any) => { - this.$scope.isLoading = false; - user.tempRole = user.role; - this.updateUserFilterTerm(user); - }; - - this.userService.editUserRole(user.userId, user.role).subscribe(onSuccess, onError); - }; - - this.$scope.saveUserChanges = (user:IUserProperties):void => { - if (user.tempRole != user.role) { - this.$scope.editUserRole(user) - } - user.isInEditMode = false; - }; - - this.$scope.deleteUser = (userId:string):void => { - - let onOk = ():void => { - this.$scope.isLoading = true; - - let onError = (response):void => { - this.$scope.isLoading = false; - console.info('onFaild', response); - }; - - let onSuccess = (response:any):void => { - _.remove(this.$scope.usersList, {userId: userId}); - this.$scope.isLoading = false; - }; - this.userService.deleteUser(userId).subscribe(onSuccess, onError); - }; - - let title:string = this.$filter('translate')("USER_MANAGEMENT_VIEW_DELETE_MODAL_TITLE"); - let message:string = this.$filter('translate')("USER_MANAGEMENT_VIEW_DELETE_MODAL_TEXT"); - this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk); - }; - this.$scope.getTitle = (role:string):string => { return role.toLowerCase().replace('governor', 'governance_Rep').replace('_', ' '); }; - this.$scope.clearForm = ():void => { - if (!this.$scope.editForm['contactId'].$viewValue && !this.$scope.editForm['role'].$viewValue) { - this.$scope.editForm.$setPristine(); - } - //if(this.$scope.editForm['contactId'].$viewValue === '' && this.$scope.editForm['role'].$viewValue){ - // this.$scope.editForm.$setPristine(); - //} - }; } } diff --git a/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view.html b/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view.html index 9322ab00aa..89fd280205 100644 --- a/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view.html +++ b/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management-view.html @@ -13,7 +13,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -
    @@ -22,48 +21,6 @@
    -
    -
    -
    -
    - -
    -
    - - -
    - - -
    -
    -
    - -
    - -
    -
    - -
    -
    @@ -74,15 +31,13 @@
    {{header.title}}
    -
    -
    {{user.firstName || '---'}}
    @@ -91,25 +46,10 @@
    {{user.email || '---'}}
    -
    {{user.lastLoginTime == 0 ? 'Waiting' : (user.lastLoginTime | date:'MM/dd/yyyy')}}
    -
    - - -
    -
    - -
    -
    diff --git a/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management.less b/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management.less index 934faab9e7..d1528492de 100644 --- a/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management.less +++ b/catalog-ui/src/app/view-models/admin-dashboard/user-management/user-management.less @@ -4,8 +4,7 @@ label { .i_17; } - .sdc-user-management-top-bar-form-input, - .sdc-user-management-top-bar-form-select { + .sdc-user-management-top-bar-form-input { .b_9; color: @color_b; height: 28px; @@ -29,57 +28,6 @@ top: 49px; } } - .vertical-border-container { - min-width: 50px; - margin: 0px auto; - - .vertical-border { - - width: 1px; - height: 70px; - background-color: @color_e; - display: table; - margin: 0 auto; - } - } - - .sdc-user-management-top-bar-wrapper { - display: flex; - } - - .sdc-user-management-top-bar-title { - .i_17; - font-weight: bold; - } - - .sdc-user-management-top-bar-create-user-container { - - display: flex; - flex-direction: column; - position: relative; - float: right; - padding-top: 0px; - text-align: left; - width: 650px; - - label { - margin-bottom: 20px; - } - - .sdc-user-management-top-bar-form-container { - width: 233px; - margin-right: 35px; - } - - .sdc-user-management-top-bar-create-btn { - .w-sdc-btn-light-green; - height: 30px; - width: 100px; - line-height: 0px; - padding-bottom: 3px; - margin-right: 0px; - } - } } @@ -147,9 +95,6 @@ } } } - &.sdc-user-management-table-row-edit-mode { - .bg_j; - } div { border-right: 1px solid @border_color_d; @@ -176,33 +121,6 @@ } } - - .sdc-user-management-table-btn-col { - - line-height: 0px; - text-align: center; - .sdc-user-management-table-delete-btn { - background-color: transparent; - border: none; - .sprite; - .sprite.e-sdc-small-icon-delete; - opacity: 0.7; - } - .sdc-user-management-table-edit-btn { - background-color: transparent; - border: none; - .sprite; - .e-sdc-small-icon-pencil; - opacity: 0.7; - } - .sdc-user-management-table-save-btn { - background-color: transparent; - border: none; - .sprite; - .sprite.e-sdc-green-save; - } - } - } .sdc-user-management-flex-container { diff --git a/catalog-ui/src/app/view-models/catalog/catalog-view-model.ts b/catalog-ui/src/app/view-models/catalog/catalog-view-model.ts deleted file mode 100644 index 8840afd79d..0000000000 --- a/catalog-ui/src/app/view-models/catalog/catalog-view-model.ts +++ /dev/null @@ -1,680 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import * as _ from "lodash"; -import {Component, IMainCategory, IGroup, IConfigStatuses, IAppMenu, IAppConfigurtaion, IUserProperties, ISubCategory, ICategoryBase} from "app/models"; -import {EntityService, CacheService} from "app/services"; -import {ComponentFactory, ResourceType, MenuHandler, ChangeLifecycleStateHandler} from "app/utils"; -import {UserService} from "../../ng2/services/user.service"; -import {ArchiveService} from "../../ng2/services/archive.service"; -import { ICatalogSelector, CatalogSelectorTypes } from "../../models/catalogSelector"; -import {IConfigStatus} from "../../models/app-config"; - -interface Checkboxes { - componentTypes:Array; - resourceSubTypes:Array; -} - -interface CheckboxesFilter { - // Types - selectedComponentTypes:Array; - selectedResourceSubTypes:Array; - // Categories - selectedCategoriesModel:Array; - // Statuses - selectedStatuses:Array>; -} - -interface Gui { - isLoading:boolean; - onComponentSubTypesClick:Function; - onComponentTypeClick:Function; - onCategoryClick:Function; - onStatusClick:Function; - changeFilterTerm:Function; -} - -interface IFilterParams { - components: string[]; - categories: string[]; - statuses: (string)[]; - order: [string, boolean]; - term: string; - active: boolean; -} - -interface ICategoriesMap { - [key: string]: { - category: ICategoryBase, - parent: ICategoryBase - } -} - -export interface ICatalogViewModelScope extends ng.IScope { - checkboxes:Checkboxes; - checkboxesFilter:CheckboxesFilter; - gui:Gui; - - categories:Array; - confStatus:IConfigStatuses; - sdcMenu:IAppMenu; - catalogFilterdItems:Array; - expandedSection:Array; - actionStrategy:any; - user:IUserProperties; - catalogMenuItem:any; - version:string; - sortBy:string; - reverse:boolean; - vfcmtType:string; - - //this is for UI paging - numberOfItemToDisplay:number; - isAllItemDisplay:boolean; - catalogFilteredItemsNum:number; - changeLifecycleState(entity:any, state:string):void; - sectionClick (section:string):void; - order(sortBy:string):void; - getElementFoundTitle(num:number):string; - goToComponent(component:Component):void; - raiseNumberOfElementToDisplay():void; - - selectedCatalogItem: ICatalogSelector; - catalogSelectorItems: Array; - showCatalogSelector: boolean; - catalogAllItems:Array; /* fake data */ - elementFoundTitle: string; - elementTypeTitle: string; - - selectLeftSwitchItem (item: ICatalogSelector): void; -} - -export class CatalogViewModel { - static '$inject' = [ - '$scope', - '$filter', - 'Sdc.Services.EntityService', - 'sdcConfig', - 'sdcMenu', - '$state', - '$q', - 'UserServiceNg2', - 'Sdc.Services.CacheService', - 'ComponentFactory', - 'ChangeLifecycleStateHandler', - 'MenuHandler', - 'ArchiveServiceNg2' - ]; - - private defaultFilterParams:IFilterParams = { - components: [], - categories: [], - statuses: [], - order: ['lastUpdateDate', true], - term: '', - active: true - }; - private categoriesMap:ICategoriesMap; - - constructor(private $scope:ICatalogViewModelScope, - private $filter:ng.IFilterService, - private EntityService:EntityService, - private sdcConfig:IAppConfigurtaion, - private sdcMenu:IAppMenu, - private $state:ng.ui.IStateService, - private $q:ng.IQService, - private userService:UserService, - private cacheService:CacheService, - private ComponentFactory:ComponentFactory, - private ChangeLifecycleStateHandler:ChangeLifecycleStateHandler, - private MenuHandler:MenuHandler, - private ArchiveService:ArchiveService - ) { - - - this.initLeftSwitch(); - this.initScopeMembers(); - this.loadFilterParams(); - this.initCatalogData(); // Async task to get catalog from server. - this.initScopeMethods(); - } - - - private initLeftSwitch = ():void => { - this.$scope.showCatalogSelector = false; - - this.$scope.catalogSelectorItems = [ - {value: CatalogSelectorTypes.Active, title: "Active Items", header: "Active"}, - {value: CatalogSelectorTypes.Archive, title: "Archive", header: "Archived"} - ]; - // set active items is default - this.$scope.selectedCatalogItem = this.$scope.catalogSelectorItems[0]; - }; - - private initCatalogData = ():void => { - if(this.$scope.selectedCatalogItem.value === CatalogSelectorTypes.Archive){ - this.getArchiveCatalogItems(); - } else { - this.getActiveCatalogItems(); - } - }; - - private initScopeMembers = ():void => { - // Gui init - this.$scope.gui = {}; - this.$scope.numberOfItemToDisplay = 0; - this.$scope.categories = this.cacheService.get('serviceCategories').concat(this.cacheService.get('resourceCategories')).map((cat) => cat); - this.$scope.sdcMenu = this.sdcMenu; - this.$scope.confStatus = this.sdcMenu.statuses; - this.$scope.expandedSection = ["type", "category", "status"]; - this.$scope.user = this.userService.getLoggedinUser(); - this.$scope.catalogMenuItem = this.sdcMenu.catalogMenuItem; - - // Checklist init - this.$scope.checkboxes = {}; - this.$scope.checkboxes.componentTypes = ['Resource', 'Service']; - this.$scope.checkboxes.resourceSubTypes = ['VF', 'VFC', 'CR', 'PNF', 'CP', 'VL']; - this.categoriesMap = this.initCategoriesMap(); - - this.initCheckboxesFilter(); - this.$scope.version = this.cacheService.get('version'); - this.$scope.sortBy = 'lastUpdateDate'; - this.$scope.reverse = true; - - }; - - private initCheckboxesFilter() { - // Checkboxes filter init - this.$scope.checkboxesFilter = {}; - this.$scope.checkboxesFilter.selectedComponentTypes = []; - this.$scope.checkboxesFilter.selectedResourceSubTypes = []; - this.$scope.checkboxesFilter.selectedCategoriesModel = []; - this.$scope.checkboxesFilter.selectedStatuses = []; - } - - private initCategoriesMap(categoriesList?:(ICategoryBase)[], parentCategory:ICategoryBase=null): ICategoriesMap { - categoriesList = (categoriesList) ? categoriesList : this.$scope.categories; - - // Init categories map - return categoriesList.reduce((acc, cat) => { - acc[cat.uniqueId] = { - category: cat, - parent: parentCategory - }; - const catChildren = ((cat).subcategories) - ? (cat).subcategories - : (((cat).groupings) - ? (cat).groupings - : null); - if (catChildren) { - Object.assign(acc, this.initCategoriesMap(catChildren, cat)); - } - return acc; - }, {}); - } - - private initScopeMethods = ():void => { - this.$scope.selectLeftSwitchItem = (item: ICatalogSelector): void => { - - if (this.$scope.selectedCatalogItem.value !== item.value) { - this.$scope.selectedCatalogItem = item; - switch (item.value) { - case CatalogSelectorTypes.Active: - this.getActiveCatalogItems(true); - break; - - case CatalogSelectorTypes.Archive: - this.getArchiveCatalogItems(true); - break; - } - this.changeFilterParams({active: (item.value === CatalogSelectorTypes.Active)}) - } - }; - - this.$scope.sectionClick = (section: string): void => { - let index: number = this.$scope.expandedSection.indexOf(section); - if (index !== -1) { - this.$scope.expandedSection.splice(index, 1); - } else { - this.$scope.expandedSection.push(section); - } - }; - - - this.$scope.order = (sortBy: string): void => {//default sort by descending last update. default for alphabetical = ascending - this.changeFilterParams({ - order: (this.$scope.filterParams.order[0] === sortBy) - ? [sortBy, !this.$scope.filterParams.order[1]] - : [sortBy, sortBy === 'lastUpdateDate'] - }); - }; - - - this.$scope.goToComponent = (component: Component): void => { - this.$scope.gui.isLoading = true; - this.$state.go('workspace.general', {id: component.uniqueId, type: component.componentType.toLowerCase()}); - }; - - - // Will print the number of elements found in catalog - this.$scope.getNumOfElements = (num:number):string => { - if (!num || num === 0) { - return `No ${this.$scope.selectedCatalogItem.header} Elements found`; - } else if (num === 1) { - return `1 ${this.$scope.selectedCatalogItem.header} Element found`; - } else { - return num + ` ${this.$scope.selectedCatalogItem.header} Elements found`; - } - }; - - /** - * Select | unselect sub resource when resource is clicked | unclicked. - * @param type - */ - this.$scope.gui.onComponentTypeClick = (compType: string, checked?: boolean): void => { - let components = angular.copy(this.$scope.filterParams.components); - const compIdx = components.indexOf(compType); - checked = (checked !== undefined) ? checked : compIdx === -1; - if (checked && compIdx === -1) { - components.push(compType); - components = this.cleanSubsFromList(components); - } else if (!checked && compIdx !== -1) { - components.splice(compIdx, 1); - } - this.changeFilterParams({ - components: components - }); - }; - - /** - * Selecting | unselect resources when sub resource is clicked | unclicked. - */ - this.$scope.gui.onComponentSubTypesClick = (compSubType: string, compType: string, checked?: boolean): void => { - const componentSubTypesCheckboxes = this.$scope.checkboxes[compType.toLowerCase() + 'SubTypes']; - if (componentSubTypesCheckboxes) { - let components = angular.copy(this.$scope.filterParams.components); - let componentSubTypes = components.filter((st) => st.startsWith(compType + '.')); - - const compSubTypeValue = compType + '.' + compSubType; - const compSubTypeValueIdx = components.indexOf(compSubTypeValue); - checked = (checked !== undefined) ? checked : compSubTypeValueIdx === -1; - if (checked && compSubTypeValueIdx === -1) { - components.push(compSubTypeValue); - componentSubTypes.push(compSubTypeValue); - - // if all sub types are checked, then check the main component type - if (componentSubTypes.length === componentSubTypesCheckboxes.length) { - this.$scope.gui.onComponentTypeClick(compType, true); - return; - } - } else if (!checked) { - const compIdx = components.indexOf(compType); - // if sub type exists, then remove it - if (compSubTypeValueIdx !== -1) { - components.splice(compSubTypeValueIdx, 1); - } - // else, if sub type doesn't exists, but its parent main component type exists, - // then remove the main type and push all sub types except the current - else if (compIdx !== -1) { - components.splice(compIdx, 1); - componentSubTypesCheckboxes.forEach((st) => { - if (st !== compSubType) { - components.push(compType + '.' + st); - } - }); - } - } - - this.changeFilterParams({ - components - }); - } - }; - - this.$scope.gui.onCategoryClick = (category: ICategoryBase, checked?: boolean): void => { - let categories: string[] = angular.copy(this.$scope.filterParams.categories); - let parentCategory: ICategoryBase = this.categoriesMap[category.uniqueId].parent; - - // add the category to selected categories list - const categoryIdx = categories.indexOf(category.uniqueId); - checked = (checked !== undefined) ? checked : categoryIdx === -1; - if (checked && categoryIdx === -1) { - categories.push(category.uniqueId); - - // check if all parent category children are checked, then check the parent category - if (parentCategory) { - if (this.getParentCategoryChildren(parentCategory).every((ch) => categories.indexOf(ch.uniqueId) !== -1)) { - this.$scope.gui.onCategoryClick(parentCategory, true); - return; - } - } - - categories = this.cleanSubsFromList(categories); - } else if (!checked) { - // if category exists, then remove it - if (categoryIdx !== -1) { - categories.splice(categoryIdx, 1); - } - // else, if category doesn't exists, but one of its parent categories exists, - // then remove that parent category and push all its children categories except the current - else { - let prevParentCategory: ICategoryBase = category; - let additionalCategories: string[] = []; - while (parentCategory) { - // add parent category children to list for replacing the parent category (if will be found later) - additionalCategories = additionalCategories.concat( - this.getParentCategoryChildren(parentCategory) - .filter((ch) => ch.uniqueId !== prevParentCategory.uniqueId) - .map((ch) => ch.uniqueId)); - - const parentCategoryIdx = categories.indexOf(parentCategory.uniqueId); - if (parentCategoryIdx !== -1) { - categories.splice(parentCategoryIdx, 1); - categories = categories.concat(additionalCategories); - break; - } else { - prevParentCategory = parentCategory; - parentCategory = this.categoriesMap[parentCategory.uniqueId].parent; - } - } - } - } - - this.changeFilterParams({ - categories - }); - }; - - this.$scope.gui.onStatusClick = (statusKey: string, status: IConfigStatus, checked?: boolean) => { - const statuses = angular.copy(this.$scope.filterParams.statuses); - - // add the status key to selected statuses list - const statusIdx = statuses.indexOf(statusKey); - checked = (checked !== undefined) ? checked : statusIdx === -1; - if (checked && statusIdx === -1) { - statuses.push(statusKey); - } else if (!checked && statusIdx !== -1) { - statuses.splice(statusIdx, 1); - } - - this.changeFilterParams({ - statuses - }); - }; - - this.$scope.gui.changeFilterTerm = (filterTerm: string) => { - this.changeFilterParams({ - term: filterTerm - }); - }; - - this.$scope.raiseNumberOfElementToDisplay = (): void => { - this.$scope.numberOfItemToDisplay = this.$scope.numberOfItemToDisplay + 35; - if (this.$scope.catalogFilterdItems) { - this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.catalogFilterdItems.length; - } - }; - - } - - private getAllCategoryChildrenIdsFlat(category:ICategoryBase) { - let catChildrenIds = []; - if ((category).subcategories) { - catChildrenIds = (category).subcategories.reduce((acc, scat) => { - return acc.concat(this.getAllCategoryChildrenIdsFlat(scat)); - }, (category).subcategories.map((scat) => scat.uniqueId)); - } - else if ((category).groupings) { - catChildrenIds = (category).groupings.map((g) => g.uniqueId); - } - return catChildrenIds; - } - - private getParentCategoryChildren(parentCategory:ICategoryBase): ICategoryBase[] { - if ((parentCategory).subcategories) { - return (parentCategory).subcategories; - } else if ((parentCategory).groupings) { - return (parentCategory).groupings; - } - return []; - } - - private cleanSubsFromList(list:Array, delimiter:string='.', removeSubsList?:Array) { - let curRemoveSubsList = (removeSubsList || list).slice().sort(); // by default remove any children of any item in list - while (curRemoveSubsList.length) { - const curRemoveSubItem = curRemoveSubsList.shift(); - const removeSubListFilter = (x) => !x.startsWith(curRemoveSubItem + delimiter); - list = list.filter(removeSubListFilter); - curRemoveSubsList = curRemoveSubsList.filter(removeSubListFilter); - } - return list; - } - - private applyFilterParamsToView(filterParams:IFilterParams) { - // reset checkboxes filter - this.initCheckboxesFilter(); - - this.applyFilterParamsComponents(filterParams); - this.applyFilterParamsCategories(filterParams); - this.applyFilterParamsStatuses(filterParams); - this.applyFilterParamsOrder(filterParams); - this.applyFilterParamsTerm(filterParams); - } - - private applyFilterParamsComponents(filterParams:IFilterParams) { - const componentList = []; - const componentSubTypesLists = {}; - filterParams.components.forEach((compStr) => { - const compWithSub = compStr.split('.', 2); - const mainComp = compWithSub[0]; - const subComp = compWithSub[1]; - if (!subComp) { // main component type - componentList.push(mainComp); - - // if component type has sub types list, then add all component sub types - const checkboxesSubTypeKey = mainComp.toLowerCase() + 'SubTypes'; - if (this.$scope.checkboxes.hasOwnProperty(checkboxesSubTypeKey)) { - componentSubTypesLists[mainComp] = angular.copy(this.$scope.checkboxes[checkboxesSubTypeKey]); - } - } else { // sub component type - // init component sub types list - if (!componentSubTypesLists.hasOwnProperty(mainComp)) { - componentSubTypesLists[mainComp] = []; - } - // add sub type to list if not exist - if (componentSubTypesLists[mainComp].indexOf(subComp) === -1) { - componentSubTypesLists[mainComp].push(subComp); - } - } - }); - this.$scope.checkboxesFilter.selectedComponentTypes = componentList; - Object.keys(componentSubTypesLists).forEach((tKey) => { - const compSelectedSubTypeKey = 'selected' + tKey + 'SubTypes'; - if (this.$scope.checkboxesFilter.hasOwnProperty(compSelectedSubTypeKey)) { - this.$scope.checkboxesFilter[compSelectedSubTypeKey] = componentSubTypesLists[tKey]; - } - }); - - let selectedCatalogIndex = filterParams.active ? CatalogSelectorTypes.Active : CatalogSelectorTypes.Archive; - this.$scope.selectedCatalogItem = this.$scope.catalogSelectorItems[selectedCatalogIndex]; - - } - - private applyFilterParamsCategories(filterParams:IFilterParams) { - this.$scope.checkboxesFilter.selectedCategoriesModel = filterParams.categories.reduce((acc, c) => { - acc.push(c); - const cat = this.categoriesMap[c].category; - if (cat) { - acc = acc.concat(this.getAllCategoryChildrenIdsFlat(cat)); - } - return acc; - }, []); - } - - private getActiveCatalogItems(forceReload?: boolean): void { - - if (forceReload || this.componentShouldReload()) { - this.$scope.gui.isLoading = true; - let onSuccess = (followedResponse:Array):void => { - this.updateCatalogItems(followedResponse); - this.$scope.gui.isLoading = false; - this.cacheService.set('breadcrumbsComponentsState', this.$state.current.name); //catalog - this.cacheService.set('breadcrumbsComponents', followedResponse); - }; - - let onError = ():void => { - console.info('Failed to load catalog CatalogViewModel::getActiveCatalogItems'); - this.$scope.gui.isLoading = false; - }; - this.EntityService.getCatalog().then(onSuccess, onError); - } else { - let cachedComponents = this.cacheService.get('breadcrumbsComponents'); - this.updateCatalogItems(cachedComponents); - } - } - - private getArchiveCatalogItems(forceReload?: boolean): void { - if(forceReload || !this.cacheService.contains("archiveComponents")) { - this.$scope.gui.isLoading = true; - let onSuccess = (followedResponse:Array):void => { - this.cacheService.set("archiveComponents", followedResponse); - this.updateCatalogItems(followedResponse); - this.$scope.gui.isLoading = false; - }; - - let onError = ():void => { - console.info('Failed to load catalog CatalogViewModel::getArchiveCatalogItems'); - this.$scope.gui.isLoading = false; - }; - - this.ArchiveService.getArchiveCatalog().subscribe(onSuccess, onError); - } else { - let archiveCache = this.cacheService.get("archiveComponents"); - this.updateCatalogItems(archiveCache); - } - - } - - private updateCatalogItems = (items:Array):void => { - this.$scope.catalogFilterdItems = items; - this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.catalogFilterdItems.length; - this.$scope.categories = this.cacheService.get('serviceCategories').concat(this.cacheService.get('resourceCategories')); - } - - private componentShouldReload = ():boolean => { - let breadcrumbsValid: boolean = (this.$state.current.name === this.cacheService.get('breadcrumbsComponentsState') && this.cacheService.contains('breadcrumbsComponents')); - return !breadcrumbsValid || this.isDefaultFilter(); - } - - private isDefaultFilter = (): boolean => { - return angular.equals(this.defaultFilterParams, this.$scope.filterParams); - } - - private applyFilterParamsStatuses(filterParams: IFilterParams) { - this.$scope.checkboxesFilter.selectedStatuses = filterParams.statuses.reduce((acc, stKey:string) => { - const status = this.$scope.confStatus[stKey]; - if (status) { - acc.push(status.values); - } - return acc; - }, []); - } - - private applyFilterParamsOrder(filterParams: IFilterParams) { - this.$scope.sortBy = filterParams.order[0]; - this.$scope.reverse = filterParams.order[1]; - } - - private applyFilterParamsTerm(filterParams: IFilterParams) { - this.$scope.search = { - filterTerm: filterParams.term - }; - } - - private loadFilterParams() { - const params = this.$state.params; - this.$scope.filterParams = angular.copy(this.defaultFilterParams); - Object.keys(params).forEach((k) => { - if (!angular.isUndefined(params[k])) { - let newVal; - let filterKey = k.substr('filter.'.length); - switch (k) { - case 'filter.components': - case 'filter.categories': - newVal = _.uniq(params[k].split(',')); - newVal = this.cleanSubsFromList(newVal); - break; - case 'filter.statuses': - newVal = _.uniq(params[k].split(',')); - break; - case 'filter.order': - newVal = params[k].startsWith('-') ? [params[k].substr(1), true] : [params[k], false]; - break; - case 'filter.term': - newVal = params[k]; - break; - case 'filter.active': - newVal = (params[k] === "true" || params[k] === true); - break; - default: - // unknown filter key - filterKey = null; - } - if (filterKey) { - this.$scope.filterParams[filterKey] = newVal; - } - } - }); - // re-set filter params with valid values - this.applyFilterParamsToView(this.$scope.filterParams); - - } - - private changeFilterParams(changedFilterParams) { - const newParams = {}; - Object.keys(changedFilterParams).forEach((k) => { - let newVal; - switch (k) { - case 'components': - case 'categories': - case 'statuses': - newVal = changedFilterParams[k] && changedFilterParams[k].length ? changedFilterParams[k].join(',') : null; - break; - case 'order': - newVal = (changedFilterParams[k][1] ? '-' : '') + changedFilterParams[k][0]; - break; - case 'term': - newVal = changedFilterParams[k] ? changedFilterParams[k] : null; - break; - case 'active': - newVal = changedFilterParams[k]; - break; - default: - return; - } - this.$scope.filterParams[k] = changedFilterParams[k]; - newParams['filter.' + k] = newVal; - }); - this.$state.go('.', newParams, {location: 'replace', notify: false}).then(() => { - this.applyFilterParamsToView(this.$scope.filterParams); - }); - } -} diff --git a/catalog-ui/src/app/view-models/catalog/catalog-view.html b/catalog-ui/src/app/view-models/catalog/catalog-view.html deleted file mode 100644 index 25fa561155..0000000000 --- a/catalog-ui/src/app/view-models/catalog/catalog-view.html +++ /dev/null @@ -1,209 +0,0 @@ - - -
    - - - - -
    - -
    -
    - {{selectedCatalogItem.title}} -
    -
     
    - -
    -
    - {{leftSwitchItem.title}} -
    -
    -
    - - - -
    -
    -
    - - Type -
    -
    -
      -
    • - - - -
        -
      • - - - -
      • -
      -
    • -
    -
    -
    - -
    -
    - - Categories -
    -
    - -
      -
    • - - - - -
        -
      • - - - - -
          -
        • - - - -
        • -
        -
      • -
      -
    • -
    - -
    -
    - - -
    -
    - - Status -
    - -
    -
      - - -
    • - - - -
      -
    • -
    -
    -
    - -
    -
    - - - - - -
    -
    -
    -    -   - -  |  -   - -
    -
    - -
    - -
    - - - - - -
    - -
    -
    - -
    - - - - -
    diff --git a/catalog-ui/src/app/view-models/catalog/catalog.less b/catalog-ui/src/app/view-models/catalog/catalog.less deleted file mode 100644 index 45556030e3..0000000000 --- a/catalog-ui/src/app/view-models/catalog/catalog.less +++ /dev/null @@ -1,362 +0,0 @@ -.sdc-catalog-container { - - .i-sdc-categories-list-item { - font-weight: normal; - } - - // Checkboxes - .i-sdc-designer-leftbar-section-content-ul { - padding: 0; - margin: 0; - - .i-sdc-designer-leftbar-section-content-ul-li { - margin-top: 5px; - - .tlv-checkbox { - font-size: 13px; - font-family: @font-opensans-medium; - color: @func_color_s; - } - } - - .i-sdc-catalog-subcategories-checkbox { - padding: 0 0 0 20px; - margin: 0; - - > li { - margin-top: 5px; - - .tlv-checkbox { - font-size:13px; - font-family: @font-opensans-regular; - } - } - - .i-sdc-catalog-grouping-checkbox { - padding: 0 0 0 20px; - margin: 0; - } - - } - - } - - .i-sdc-designer-leftbar-section-content-li { - &:last-child { - .i-sdc-categories-list-item { - margin: 0; - } - } - } - - .i-sdc-categories-list-item { - display: block; - //margin-bottom: 5px; - //padding-left: 15px; - //text-indent: -24px; - vertical-align: top; - font-weight: bold; - } - - .i-sdc-subcategories-list-item { - display: block; - //padding-left: 20px; - vertical-align: top; - font-weight: normal; - margin: 0; - //text-indent: -10px; - } - - .i-sdc-categories-list-item-icon { - display: inline-block; - float: right; - position: relative; - right: -8px; - top: 6px; - } - - .i-sdc-categories-list-item { - margin-top: 7px; - &.NOT_CERTIFIED_CHECKOUT, - &.NOT_CERTIFIED_CHECKIN { - .i-sdc-categories-list-item-icon { - background: url('/assets/styles/images/sprites/sprite-global-old.png') no-repeat -53px -2889px; - width: 14px; - height: 14px; - - } - } - - &.CERTIFIED { - .i-sdc-categories-list-item-icon { - background: url('/assets/styles/images/sprites/sprite-global-old.png') no-repeat -53px -3034px; - width: 14px; - height: 16px; - } - } - - &.READY_FOR_CERTIFICATION { - .i-sdc-categories-list-item-icon { - background: url('/assets/styles/images/sprites/sprite-global-old.png') no-repeat -53px -2985px; - width: 14px; - height: 16px; - } - } - - &.CERTIFICATION_IN_PROGRESS { - .i-sdc-categories-list-item-icon { - background: url('/assets/styles/images/sprites/sprite-global-old.png') no-repeat -53px -2934px; - width: 14px; - height: 16px; - } - } - - &.DISTRIBUTED, - &.TBD { - .i-sdc-categories-list-item-icon { - background: url('/assets/styles/images/sprites/sprite-global-old.png') no-repeat -43px -3087px; - width: 24px; - height: 14px; - - } - } - } - - .i-sdc-categories-list-input { - margin: 8px; - - } - - .i-sdc-subcategories-list-input { - - margin: 8px; - } - .i-sdc-subcategories-list-input-container { - margin: 0px 0px 0px 20px; - padding: 2px; - } - - .w-sdc-header-catalog-search-container { - display: table; - padding: 21px 0; - position: relative; - - .w-sdc-designer-leftbar-search-input { - color: #000; - width: 300px; - } - } - - .w-sdc-catalog-main { - padding: 10px 12px; - } - .w-sdc-dashboard-catalog-items-header { - .b_3; - color: @main_color_m; - font-family: OpenSans-Regular, sans-serif; - font-size: 14px; - display: inline-block; - font-style: normal; - margin-left: 11px; - b { - font-family: OpenSans-Bold, sans-serif; - color: @main_color_l; - font-weight: bold; - } - font-weight: normal; - /* padding-left: 10px; */ - } - - .w-sdc-dashboard-catalog-header-order1 { - .b_3; - font-weight: 800; - } - - .w-sdc-dashboard-catalog-sort { - .b_3; - font-weight: bold; - white-space:pre; - &:hover{ - .hand; - text-decoration: none; - .a_3; - } - &.blue { - .a_3; - } - } - - .w-sdc-catalog-sort-arrow{ - display: inline-block; - &.up{ - .b_3; - width: 0; - height: 0; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-bottom: 5px solid ; - } - &.down{ - .b_3; - width: 0; - height: 0; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-top: 5px solid; - } - } - - - .w-sdc-dashboard-catalog-header-right{ - float: right; - display: inline-block; - padding-right:34px; - } - - .w-sdc-header-catalog-search-input { - width: 420px; - display: table-cell; - padding: 0 25px 1px 10px; - border: 1px solid #bcbcbc; - .border-radius(10px); - height: 30px; - margin: 10px 30px; - outline: none; - } - - .sdc-catalog-type-filter-container { - margin-top: -1px; - } - - .i-sdc-designer-leftbar-section-title { - text-transform: uppercase; - .l_14_m; - line-height: 30px; - } - - .i-sdc-designer-leftbar-section-title-icon { - .hand; - .tlv-sprite; - .footer-close; - transition: .3s all; - margin-top: -4px; - } - - .i-sdc-designer-leftbar-section-title-text { - margin-left: 20px; - } - - /* added Michael */ - .i-sdc-designer-left-sidebar { - margin-top: 43px; - } - .i-sdc-designer-leftbar-section-left-switch-header { - text-transform: uppercase; - .l_14_m; - line-height: 40px; - width: 243px; - - font-family: OpenSans-Bold, sans-serif; - font-size: 14px; - - color: @main_color_a; - background-color: @tlv_color_t; - border: solid 1px fade(@main_color_t, 40%); - cursor: pointer; - opacity: 1; - z-index: 9999; - position: relative; - //box-shadow: 1px 0 2px #00000036; - } - .i-sdc-designer-leftbar-section-left-switch-header-text { - display: inline-block; - width: 180px; - margin-left: 20px; - } - .i-sdc-designer-leftbar-section-left-switch-header-icon { - display: inline-block; - vertical-align: middle; - } - - - .seperator-left, - .seperator-right { - border-right: solid 1px @color_m; - display: table-cell; - width: 2px; - } - - // Rotate catalog left side arrows - .i-sdc-designer-leftbar-section-title.expanded .i-sdc-designer-leftbar-section-title-icon { - transform: rotate(180deg); - } - - // Transform catalog left side sections - .i-sdc-designer-leftbar-section-title + .i-sdc-designer-leftbar-section-content { - max-height: 0px; - margin: 0 auto; - transition: all .3s; - overflow: hidden; - padding: 0 10px 0 18px; - } - - .i-sdc-designer-leftbar-section-title.expanded + .i-sdc-designer-leftbar-section-content { - max-height: 9999px; - margin: 0 auto 1px; - transition: all .3s; - padding: 10px 18px 10px 18px; - overflow: hidden; - } - -} - -.w-sdc-search-icon{ - position: absolute; - right: 40px; - top: 40px; - &.leftbar{ - top: 19px; - right: 18px; - } - &.magnification { - .sprite; - .sprite.magnification-glass; - .hand; - } - - &.cancel { - .sprite; - .sprite.clear-text; - .hand; - } -} - -/* added Michael */ -.sdc-catalog-selector-wrapper { - position: absolute; - left: 0px; - top: 42px; - width: 241px; - height: auto; - cursor: pointer; - opacity: 1; - z-index: 1000; - box-shadow: 1px 2px 3px #b1b1b1; -} - -.sdc-catalog-selector-item { - text-transform: none; - line-height: 40px; - font-family: OpenSans-Bold, sans-serif; - font-size: 14px; - color: @main_color_l; - background-color: @main_color_p; - padding-left: 20px; -} - -.sdc-catalog-selector-item:hover { - color: @main_color_a; - background-color: @tlv_color_v; -} - - diff --git a/catalog-ui/src/app/view-models/dashboard/dashboard-view-model.ts b/catalog-ui/src/app/view-models/dashboard/dashboard-view-model.ts deleted file mode 100644 index 4d084045f7..0000000000 --- a/catalog-ui/src/app/view-models/dashboard/dashboard-view-model.ts +++ /dev/null @@ -1,497 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {IConfigRoles, IAppConfigurtaion, IAppMenu, IUserProperties, Component} from "app/models"; -import {EntityService, SharingService, CacheService} from "app/services"; -import {ComponentType, ResourceType, MenuHandler, ModalsHandler, ChangeLifecycleStateHandler, SEVERITY, ComponentFactory, CHANGE_COMPONENT_CSAR_VERSION_FLAG} from "app/utils"; -import {IClientMessageModalModel} from "../modals/message-modal/message-client-modal/client-message-modal-view-model"; -import {UserService} from "../../ng2/services/user.service"; - - -export interface IDashboardViewModelScope extends ng.IScope { - - isLoading:boolean; - numberOfItemToDisplay:number; - components:Array; - folders:FoldersMenu; - roles:IConfigRoles; - user:IUserProperties; - sdcConfig:IAppConfigurtaion; - sdcMenu:IAppMenu; - sharingService:SharingService; - showTutorial:boolean; - isFirstTime:boolean; - version:string; - filterParams:DashboardFilter; - vfcmtType:string; - - changeFilterParams():void; - updateSearchTerm(newTerm:string):void; - onImportVfc(file:any):void; - onImportVf(file:any):void; - openCreateModal(componentType:ComponentType, importedFile:any):void; - openWhatsNewModal(version:string):void; - openDesignerModal(isResource:boolean, uniqueId:string):void; - setSelectedFolder(folderItem:FoldersItemsMenu):void; - entitiesCount(folderItem:FoldersItemsMenu):number; - getCurrentFolderDistributed():Array; - changeLifecycleState(entity:any, data:any):void; - goToComponent(component:Component):void; - raiseNumberOfElementToDisplay():void; - wizardDebugEdit:Function; - notificationIconCallback:Function; -} - -interface ICheckboxesFilter { - // Statuses - selectedStatuses:Array; - // distributed - distributed:Array; -} - -export interface IItemMenu { - -} - -export interface IMenuItemProperties { - text:string; - group:string; - state:string; - dist:string; - groupname:string; - states:Array; -} - -export interface IQueryFilterParams { - 'filter.term': string; - 'filter.distributed': string; - 'filter.status': string -} - - -export class DashboardFilter { - searchTerm: string; - checkboxes: ICheckboxesFilter; - - constructor(params = {}) { - this.searchTerm = params['filter.term'] || ""; - this.checkboxes = { - selectedStatuses : params['filter.status']? params['filter.status'].split(',') : [], - distributed : params['filter.distributed']? params['filter.distributed'].split(',') : [] - }; - } - - public toParam = ():IQueryFilterParams => { - return { - 'filter.term': this.searchTerm, - 'filter.distributed': this.checkboxes && this.checkboxes.distributed.join(',') || null, - 'filter.status': this.checkboxes && this.checkboxes.selectedStatuses.join(',') || null - }; - } - -} - -export class FoldersMenu { - - private _folders:Array = []; - - constructor(folders:Array) { - let self = this; - folders.forEach(function (folder:IMenuItemProperties) { - if (folder.groupname) { - self._folders.push(new FoldersItemsMenuGroup(folder)); - } else { - self._folders.push(new FoldersItemsMenu(folder)); - } - }); - self._folders[0].setSelected(true); - } - - public getFolders = ():Array => { - return this._folders; - }; - - public getCurrentFolder = ():FoldersItemsMenu => { - let menuItem:FoldersItemsMenu = undefined; - this.getFolders().forEach(function (tmpFolder:FoldersItemsMenu) { - if (tmpFolder.isSelected()) { - menuItem = tmpFolder; - } - }); - return menuItem; - }; - - public setSelected = (folder:FoldersItemsMenu):void => { - this.getFolders().forEach(function (tmpFolder:FoldersItemsMenu) { - tmpFolder.setSelected(false); - }); - folder.setSelected(true); - } - -} - -export class FoldersItemsMenu implements IItemMenu { - - public text:string; - public group:string; - public state:string; - public dist:string; - public states:Array; - - private selected:boolean = false; - - constructor(menuProperties:IMenuItemProperties) { - this.text = menuProperties.text; - this.group = menuProperties.group; - this.state = menuProperties.state; - this.states = menuProperties.states; - this.dist = menuProperties.dist; - } - - public isSelected = ():boolean => { - return this.selected; - }; - - public setSelected = (value:boolean):void => { - this.selected = value; - }; - - public isGroup = ():boolean => { - return false; - } - -} - -export class FoldersItemsMenuGroup extends FoldersItemsMenu { - - public groupname:string; - - constructor(menuProperties:IMenuItemProperties) { - super(menuProperties); - this.groupname = menuProperties.groupname; - } - - public isGroup = ():boolean => { - return true; - } - -} - -export class DashboardViewModel { - static '$inject' = [ - '$scope', - '$filter', - 'Sdc.Services.EntityService', - '$http', - 'sdcConfig', - 'sdcMenu', - '$state', - '$stateParams', - 'UserServiceNg2', - 'Sdc.Services.SharingService', - 'Sdc.Services.CacheService', - '$q', - 'ComponentFactory', - 'ChangeLifecycleStateHandler', - 'ModalsHandler', - 'MenuHandler' - ]; - - private components:Array; - - constructor(private $scope:IDashboardViewModelScope, - private $filter:ng.IFilterService, - private entityService:EntityService, - private $http:ng.IHttpService, - private sdcConfig:IAppConfigurtaion, - private sdcMenu:IAppMenu, - private $state:ng.ui.IStateService, - private $stateParams:any, - private userService:UserService, - private sharingService:SharingService, - private cacheService:CacheService, - private $q:ng.IQService, - private ComponentFactory:ComponentFactory, - private ChangeLifecycleStateHandler:ChangeLifecycleStateHandler, - private ModalsHandler:ModalsHandler, - private MenuHandler:MenuHandler) { - this.initScope(); - this.initFolders(); - this.initEntities(); - - if (this.$stateParams) { - - if (this.$state.params.folder) { - let self = this; - let folderName = this.$state.params.folder.replaceAll("_", " "); - - this.$scope.folders.getFolders().forEach(function (tmpFolder:FoldersItemsMenu) { - if (tmpFolder.text === folderName) { - self.$scope.setSelectedFolder(tmpFolder); - } - }); - } - - // Show the tutorial if needed when the dashboard page is opened. - // This is called from the welcome page. - else if (this.$stateParams.show === 'tutorial') { - this.$scope.showTutorial = true; - this.$scope.isFirstTime = true; - } - } - } - - private initFolders = ():void => { - if (this.$scope.user) { - this.$scope.folders = new FoldersMenu(this.$scope.roles[this.$scope.user.role].folder); - } - }; - - private initScope = ():void => { - let self = this; - - this.$scope.version = this.cacheService.get('version'); - this.$scope.sharingService = this.sharingService; - this.$scope.numberOfItemToDisplay = 0; - this.$scope.isLoading = false; - this.$scope.sdcConfig = this.sdcConfig; - this.$scope.sdcMenu = this.sdcMenu; - this.$scope.user = this.userService.getLoggedinUser(); - this.$scope.roles = this.sdcMenu.roles; - this.$scope.showTutorial = false; - this.$scope.isFirstTime = false; - this.$scope.vfcmtType = ResourceType.VFCMT; - this.$scope.filterParams = new DashboardFilter(this.$state.params); - - // Open onboarding modal - this.$scope.notificationIconCallback = ():void => { - this.ModalsHandler.openOnboadrdingModal('Import').then((result)=> { - //OK - if(!result.previousComponent || result.previousComponent.csarVersion != result.componentCsar.csarVersion) { - this.cacheService.set(CHANGE_COMPONENT_CSAR_VERSION_FLAG, result.componentCsar.csarVersion); - } - - this.$state.go('workspace.general', { - id: result.previousComponent && result.previousComponent.uniqueId, - componentCsar: result.componentCsar, - type: result.type - }); - }, ()=> { - // ERROR - }); - }; - - this.$scope.onImportVf = (file:any):void => { - if (file && file.filename) { - // Check that the file has valid extension. - let fileExtension:string = file.filename.split(".").pop(); - if (this.sdcConfig.csarFileExtension.indexOf(fileExtension.toLowerCase()) !== -1) { - this.$state.go('workspace.general', { - type: ComponentType.RESOURCE.toLowerCase(), - importedFile: file, - resourceType: ResourceType.VF - }); - } else { - let data:IClientMessageModalModel = { - title: self.$filter('translate')("NEW_SERVICE_RESOURCE_ERROR_VALID_CSAR_EXTENSIONS_TITLE"), - message: self.$filter('translate')("NEW_SERVICE_RESOURCE_ERROR_VALID_CSAR_EXTENSIONS", "{'extensions': '" + this.sdcConfig.csarFileExtension + "'}"), - severity: SEVERITY.ERROR - }; - this.ModalsHandler.openClientMessageModal(data); - } - } - }; - - this.$scope.onImportVfc = (file:any):void => { - if (file && file.filename) { - // Check that the file has valid extension. - let fileExtension:string = file.filename.split(".").pop(); - if (this.sdcConfig.toscaFileExtension.indexOf(fileExtension.toLowerCase()) !== -1) { - this.$state.go('workspace.general', { - type: ComponentType.RESOURCE.toLowerCase(), - importedFile: file, - resourceType: ResourceType.VFC - }); - } else { - let data:IClientMessageModalModel = { - title: self.$filter('translate')("NEW_SERVICE_RESOURCE_ERROR_VALID_TOSCA_EXTENSIONS_TITLE"), - message: self.$filter('translate')("NEW_SERVICE_RESOURCE_ERROR_VALID_TOSCA_EXTENSIONS", "{'extensions': '" + this.sdcConfig.toscaFileExtension + "'}"), - severity: SEVERITY.ERROR - }; - this.ModalsHandler.openClientMessageModal(data); - } - } - }; - - this.$scope.openCreateModal = (componentType:string, importedFile:any):void => { - if (importedFile) { - this.initEntities(true); // Return from import - } else { - this.$state.go('workspace.general', {type: componentType.toLowerCase()}); - } - - }; - - this.$scope.createPNF = ():void => { - this.$state.go('workspace.general', { - type: ComponentType.RESOURCE.toLowerCase(), - resourceType: ResourceType.PNF - }); - }; - - this.$scope.createCR = ():void => { - this.$state.go('workspace.general', { - type: ComponentType.RESOURCE.toLowerCase(), - resourceType: ResourceType.CR - }); - }; - - this.$scope.entitiesCount = (folderItem:FoldersItemsMenu):any => { - let self = this; - let total:number = 0; - if (folderItem.isGroup()) { - this.$scope.folders.getFolders().forEach(function (tmpFolder:FoldersItemsMenu) { - if (tmpFolder.group && tmpFolder.group === (folderItem).groupname) { - total = total + self._getTotalCounts(tmpFolder, self); - } - }); - } else { - total = total + self._getTotalCounts(folderItem, self); - } - return total; - }; - - this.$scope.getCurrentFolderDistributed = ():Array => { - let self = this; - let states = []; - if (this.$scope.folders) { - let folderItem:FoldersItemsMenu = this.$scope.folders.getCurrentFolder(); - if (folderItem.isGroup()) { - this.$scope.folders.getFolders().forEach(function (tmpFolder:FoldersItemsMenu) { - if (tmpFolder.group && tmpFolder.group === (folderItem).groupname) { - self._setStates(tmpFolder, states); - } - }); - } else { - self._setStates(folderItem, states); - } - } - return states; - }; - - this.$scope.setSelectedFolder = (folderItem:FoldersItemsMenu):void => { - this.$scope.folders.setSelected(folderItem); - }; - - this.$scope.goToComponent = (component:Component):void => { - this.$scope.isLoading = true; - this.$state.go('workspace.general', {id: component.uniqueId, type: component.componentType.toLowerCase()}); - }; - - this.$scope.raiseNumberOfElementToDisplay = ():void => { - this.$scope.numberOfItemToDisplay = this.$scope.numberOfItemToDisplay + 35; - if (this.$scope.components) { - this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.components.length; - } - }; - - this.$scope.updateSearchTerm = (newTerm: string):void => { - this.$scope.filterParams.searchTerm = newTerm; - }; - - this.$scope.changeFilterParams = ():void => { - this.$state.go('.', this.$scope.filterParams.toParam(), {location: 'replace', notify: false}); - }; - }; - - private _getTotalCounts(tmpFolder, self):number { - let total:number = 0; - if (tmpFolder.dist !== undefined) { - let distributions = tmpFolder.dist.split(','); - distributions.forEach((item:any) => { - total = total + self.getEntitiesByStateDist(tmpFolder.state, item).length; - }); - } - else { - total = total + self.getEntitiesByStateDist(tmpFolder.state, tmpFolder.dist).length; - } - return total; - } - - private _setStates(tmpFolder, states) { - if (tmpFolder.states !== undefined) { - tmpFolder.states.forEach(function (item:any) { - states.push({"state": item.state, "dist": item.dist}); - }); - } else { - states.push({"state": tmpFolder.state, "dist": tmpFolder.dist}); - } - } - - private initEntities = (forceReload?:boolean):void => { - - if(forceReload || this.componentShouldReload()){ - this.$scope.isLoading = true; - this.entityService.getAllComponents(true).then( - (components:Array) => { - this.cacheService.set('breadcrumbsComponentsState', this.$state.current.name); //dashboard - this.cacheService.set('breadcrumbsComponents', components); - this.components = components; - this.$scope.components = components; - this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.components.length; - this.$scope.isLoading = false; - }); - } else { - this.components = this.cacheService.get('breadcrumbsComponents'); - this.$scope.components = this.components; - this.$scope.isAllItemDisplay = this.$scope.numberOfItemToDisplay >= this.$scope.components.length; - - } - - }; - - private isDefaultFilter = (): boolean => { - let defaultFilter = new DashboardFilter(); - return angular.equals(defaultFilter, this.$scope.filterParams); - } - - private componentShouldReload = ():boolean => { - let breadcrumbsValid: boolean = (this.$state.current.name === this.cacheService.get('breadcrumbsComponentsState') && this.cacheService.contains('breadcrumbsComponents')); - return !breadcrumbsValid || this.isDefaultFilter(); - } - - private getEntitiesByStateDist = (state:string, dist:string):Array => { - let gObj:Array; - if (this.components && (state || dist)) { - gObj = this.components.filter(function (obj:Component) { - if (dist !== undefined && obj.distributionStatus === dist && obj.lifecycleState === state) { - return true; - } else if (dist === undefined && obj.lifecycleState === state) { - return true; - } - return false; - }); - } else { - gObj = []; - } - return gObj; - } -} diff --git a/catalog-ui/src/app/view-models/dashboard/dashboard-view.html b/catalog-ui/src/app/view-models/dashboard/dashboard-view.html deleted file mode 100644 index 240a74d292..0000000000 --- a/catalog-ui/src/app/view-models/dashboard/dashboard-view.html +++ /dev/null @@ -1,109 +0,0 @@ - - -
    - - - - -
    - - - -
    - -
    - - -
    -
    -
    -
    - - - - -
    -
    -
    - - -
    -
    -
    -
    -
    Import VFC - -
    -
    Import VSP
    -
    Import DCAE asset - -
    -
    -
    -
    - - - - - -
    - -
    - -
    - -
    -
    - {{folder.text}} - - - - - {{entitiesCount(folder)}} -
    -
    - -
    - - - -
    -
    - - diff --git a/catalog-ui/src/app/view-models/dashboard/dashboard.less b/catalog-ui/src/app/view-models/dashboard/dashboard.less deleted file mode 100644 index 02280cdb42..0000000000 --- a/catalog-ui/src/app/view-models/dashboard/dashboard.less +++ /dev/null @@ -1,413 +0,0 @@ -.sdc-dashboard-container { - .tlv-loader { - top: -110px; - left: 80px; - } - .sdc-hide-popover { - .popover { - display: none !important; - } - } -} - -.w-sdc-left-sidebar-nav { - margin-top: 46px; -} - -.w-sdc-main-right-container-element { - float: left; - height: 217px; - width: 217px; - margin: 10px; - position: relative; -} - -.w-sdc-main-right-container-element-details-container { - position: absolute; - top: 165px; - left: 50px; -} - -.w-sdc-main-right-container-element-name { - font-weight: bold; -} - -.w-sdc-main-right-container-element-owner { - -} - -//////////////////////////////Cards//////////////////// -.w-sdc-dashboard-card-new { - border: 2px dashed @color_m; - .border-radius(2px); - cursor: pointer; - display: inline-block; - height: 198px; - margin: 11px; - position: relative; - vertical-align: middle; - width: 202px; -} - -.w-sdc-dashboard-card-new-content { - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - height: 100%; -} - -.w-sdc-dashboard-card-new-content-plus { - .sprite-new; - .add-icon; - position: relative; - margin-bottom: 20px; - - &:after { - .n_14_m; - content: 'ADD'; - position: absolute; - top: 25px; - left: -3px; - vertical-align: -50%; - } -} - -.w-sdc-dashboard-card-import-content-plus { - .sprite-new; - .import-icon; - position: relative; - margin-bottom: 20px; - - &:after { - .n_14_m; - content: 'IMPORT'; - position: absolute; - top: 25px; - left: -16px; - vertical-align: -50%; - } -} - -.sdc-dashboard-create-element-container, -.sdc-dashboard-import-element-container { - - width: 140px; - - .tlv-btn.import-dcae { - padding: 0; - } - - .tlv-btn { - position: relative; - width: 100%; - margin-bottom: 10px; - - &:last-child { - margin-bottom: 0; - } - } - - input[type="file"] { - cursor: inherit; - filter: alpha(opacity=0); - opacity: 0; - position: absolute; - top: 0; - left: 0; - width: 138px; - height: 30px; - } -} - -.w-sdc-dashboard-card { - width: 204px; - height: 200px; - background-color: @main_color_p; - .border-radius(2px); - .box-shadow(0px 2px 2px 0px rgba(24, 24, 25, 0.05)); - display: inline-block; - margin: 10px; - position: relative; - vertical-align: middle; - border: solid 1px @main_color_p; - - &:hover { - border: solid 1px @main_color_o; - .box-shadow(3px 3px 2px 0px rgba(24, 24, 25, 0.05)); - } - - &:active { - border: solid 1px @main_color_c; - .box-shadow(3px 3px 2px 0px rgba(24, 24, 25, 0.05)); - } -} - -.w-sdc-dashboard-card-body { - .hand; - border-bottom: 1px solid @color_j; - height: 155px; - position: relative; - text-align: center; -} - -.w-sdc-dashboard-card-description { - .c_3; - .hand; - background-color: rgba(57, 73, 84, 0.9); - border-radius: 4px 4px 0 0; - bottom: 0; - left: 0; - opacity: 0; - padding: 10px; - position: absolute; - right: 0; - text-align: left; - top: 0; - word-wrap: break-word; - z-index: 4; - min-height: 100px; - overflow: hidden; -} - - -.w-sdc-dashboard-card-schema { - margin-top: 30px; -} - -.w-sdc-dashboard-card-edit { - .hand; - position: absolute; - right: 13px; - top: 15px; - z-index: 2; -} - -.w-sdc-dashboard-card-footer { - padding: 3px 12px 10px 12px; - position: relative; -} - -.w-sdc-dashboard-card-avatar { - .uppercase; - border-radius: 50%; - display: inline-block; - position: absolute; - left: -6px; - text-align: center; - top: -6px; - - span { - - background-color: @main_color_p; - .border-radius(15px); - color: @color_c; - content: ''; - height: 30px; - text-align: center; - display: block; - border: solid 2px #ECEFF3; - padding: 3px 10px 2px 10px; - - &.VF { - .j_14_m; - &::before { - content: 'VF'; - } - } - - &.VFC { - .j_14_m; - &::before { - content: 'VFC'; - } - } - - &.CP { - .j_14_m; - &::before { - content: 'CP'; - } - } - - &.VL { - .j_14_m; - &::before { - content: 'VL'; - } - } - - &.SERVICE { - .c_14_m; - &::before { - content: 'S'; - } - } - - &.green { - .d_12; - &::before { - content: 'R'; - } - } - &.red { - .r_12; - &::before { - content: 'S'; - } - } - &.dblack { - .s_12; - &::before { - content: 'P'; - } - } - } -} - -.w-sdc-dashboard-card-info { - display: inline-block; - vertical-align: middle; - max-width: 165px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.w-sdc-dashboard-card-info-name-container{ - position: absolute; - bottom: 0; - left: 0; - margin: 0 0 2px 10px; -} -.w-sdc-dashboard-card-info-name { - .m_14_m; - display: inline-block; - vertical-align: middle; - max-width: 165px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.w-sdc-dashboard-card-info-lifecycleState { - .m_13_m; - display: inline-block; - vertical-align: middle; - max-width: 165px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.w-sdc-dashboard-card-info-user { - .n_13_r; - line-height: 18px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - width: 100%; -} - -.w-sdc-dashboard-card-menu-button { - display: inline-block; - padding: 12px 0 0 10px; - position: absolute; - right: 12px; - top: 8px; - border-left: solid 1px @color_k; - height: 42px; - - &:hover { - .w-sdc-dashboard-card-menu { - display: block; - } - } -} - -.w-sdc-dashboard-card-menu { - .bg_c; - border-radius: 0 0 4px 4px; - border-top: 3px solid @color_a; - box-shadow: 0 2px 2px 0px rgba(0, 0, 0, 0.2); - color: @color_s; - display: none; - min-height: 30px; - padding: 9px 0; - position: absolute; - right: -27px; - width: 208px; - z-index: 9; - max-height: 164px; - - &::before { - //TODO: Missing image for small blue triangle. - background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDE0IDc5LjE1Njc5NywgMjAxNC8wOC8yMC0wOTo1MzowMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkE1OTIzNDI1MENFQjExRTU4ODRERTI1MDM2REZCOUYzIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkE1OTIzNDI2MENFQjExRTU4ODRERTI1MDM2REZCOUYzIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QTU5MjM0MjMwQ0VCMTFFNTg4NERFMjUwMzZERkI5RjMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QTU5MjM0MjQwQ0VCMTFFNTg4NERFMjUwMzZERkI5RjMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4gBXTlAAAAOElEQVR42mK0rp7NgASMgZgFiE/CBJjQJPcA8U4gNkdXAJMUAGJ+ZEVMaJIwAFfEhEUSRRFAgAEAVtgJyiLAPWAAAAAASUVORK5CYII='); - content: ''; - display: block; - height: 21px; - position: absolute; - right: 24px; - top: -24px; - width: 184px; - background-repeat: no-repeat; - background-position: 175px 16px; - } -} - -.i-sdc-dashboard-card-menu-item { - .hand; - line-height: 24px; - padding: 0 10px; - &:hover { .a_7; } -} - -.w-sdc-dashboard-card-info-lifecycleState-icon{ - position:absolute; - bottom:18px; - right:10px; -} - -// Same for dashboard and catalog view. -.w-sdc-dashboard-card-schema-image { - position: absolute; - top: 41%; - - //TODO: Israel - remove this after getting the services sprite. - height: 45px; - width: 53px; - background-repeat: no-repeat; - - // Center the icon vertical and horizontal. - margin: auto; - left: 0; - right: 0; - top: -10px; - bottom: 0; -} - -/* dashboard card main icons */ -.w-sdc-dashboard-card-schema-image.service { .s-sdc-service } -.w-sdc-dashboard-card-schema-image.resource { .s-sdc-resource } - -/* dashboard card statuses icons */ -.w-sdc-dashboard-card-edit.NOT_CERTIFIED_CHECKIN { .sprite; .s-sdc-state.NOT_CERTIFIED_CHECKIN; } -.w-sdc-dashboard-card-edit.NOT_CERTIFIED_CHECKOUT { .sprite; .s-sdc-state.NOT_CERTIFIED_CHECKOUT; } -.w-sdc-dashboard-card-edit.CERTIFIED { .sprite; .s-sdc-state.CERTIFIED; } -.w-sdc-dashboard-card-edit.READY_FOR_CERTIFICATION { .sprite; .s-sdc-state.READY_FOR_CERTIFICATION; } -.w-sdc-dashboard-card-edit.CERTIFICATION_IN_PROGRESS { .sprite; .s-sdc-state.CERTIFICATION_IN_PROGRESS; } -.w-sdc-dashboard-card-edit.DISTRIBUTED { .sprite; .s-sdc-state.DISTRIBUTED; } - -.w-sdc-dashboard-card-avatar.green + .w-sdc-dashboard-card-edit.NOT_CERTIFIED_CHECKIN { .sprite; .s-sdc-state.NOT_CERTIFIED_CHECKIN.green; } -.w-sdc-dashboard-card-avatar.green + .w-sdc-dashboard-card-edit.NOT_CERTIFIED_CHECKOUT { .sprite; .s-sdc-state.NOT_CERTIFIED_CHECKOUT.green; } -.w-sdc-dashboard-card-avatar.green + .w-sdc-dashboard-card-edit.CERTIFIED { .sprite; .s-sdc-state.CERTIFIED.green; } -.w-sdc-dashboard-card-avatar.green + .w-sdc-dashboard-card-edit.READY_FOR_CERTIFICATION { .sprite; .s-sdc-state.READY_FOR_CERTIFICATION.green; } -.w-sdc-dashboard-card-avatar.green + .w-sdc-dashboard-card-edit.CERTIFICATION_IN_PROGRESS { .sprite; .s-sdc-state.CERTIFICATION_IN_PROGRESS.green; } -.w-sdc-dashboard-card-avatar.green + .w-sdc-dashboard-card-edit.DISTRIBUTED { .sprite; .s-sdc-state.DISTRIBUTED.green; } - -.w-sdc-dashboard-card-avatar.red + .w-sdc-dashboard-card-edit.NOT_CERTIFIED_CHECKIN { .sprite; .s-sdc-state.NOT_CERTIFIED_CHECKIN.red; } -.w-sdc-dashboard-card-avatar.red + .w-sdc-dashboard-card-edit.NOT_CERTIFIED_CHECKOUT { .sprite; .s-sdc-state.NOT_CERTIFIED_CHECKOUT.red; } -.w-sdc-dashboard-card-avatar.red + .w-sdc-dashboard-card-edit.CERTIFIED { .sprite; .s-sdc-state.CERTIFIED.red; } -.w-sdc-dashboard-card-avatar.red + .w-sdc-dashboard-card-edit.READY_FOR_CERTIFICATION { .sprite; .s-sdc-state.READY_FOR_CERTIFICATION.red; } -.w-sdc-dashboard-card-avatar.red + .w-sdc-dashboard-card-edit.CERTIFICATION_IN_PROGRESS { .sprite; .s-sdc-state.CERTIFICATION_IN_PROGRESS.red; } -.w-sdc-dashboard-card-avatar.red + .w-sdc-dashboard-card-edit.DISTRIBUTED { .sprite; .s-sdc-state.DISTRIBUTED.red; } diff --git a/catalog-ui/src/app/view-models/dcae-app/dcae-app-view-model.ts b/catalog-ui/src/app/view-models/dcae-app/dcae-app-view-model.ts index 19bc548e74..e6ac97085a 100644 --- a/catalog-ui/src/app/view-models/dcae-app/dcae-app-view-model.ts +++ b/catalog-ui/src/app/view-models/dcae-app/dcae-app-view-model.ts @@ -22,7 +22,7 @@ import * as _ from "lodash"; import {MenuItemGroup, MenuItem} from "app/utils"; import {BreadcrumbsPath, BreadcrumbsMenu} from "../onboard-vendor/onboard-vendor-view-model"; -import {CacheService} from "app/services"; +import {CacheService} from "app/services-ng2"; import {IUserProperties} from "app/models"; export class TestData { diff --git a/catalog-ui/src/app/view-models/dcae-app/dcae-app-view.html b/catalog-ui/src/app/view-models/dcae-app/dcae-app-view.html index 9dbe289ba2..a1e084108a 100644 --- a/catalog-ui/src/app/view-models/dcae-app/dcae-app-view.html +++ b/catalog-ui/src/app/view-models/dcae-app/dcae-app-view.html @@ -13,7 +13,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -
    diff --git a/catalog-ui/src/app/view-models/dcae-app/dcae-app.less b/catalog-ui/src/app/view-models/dcae-app/dcae-app.less index 71a3101412..1e091e957d 100644 --- a/catalog-ui/src/app/view-models/dcae-app/dcae-app.less +++ b/catalog-ui/src/app/view-models/dcae-app/dcae-app.less @@ -76,22 +76,6 @@ } } - &.READY_FOR_CERTIFICATION { - .i-sdc-categories-list-item-icon { - background: url('/assets/styles/images/sprites/sprite-global-old.png') no-repeat -53px -2985px; - width: 14px; - height: 16px; - } - } - - &.CERTIFICATION_IN_PROGRESS { - .i-sdc-categories-list-item-icon { - background: url('/assets/styles/images/sprites/sprite-global-old.png') no-repeat -53px -2934px; - width: 14px; - height: 16px; - } - } - &.DISTRIBUTED, &.TBD { .i-sdc-categories-list-item-icon { diff --git a/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form-view-model.ts b/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form-view-model.ts deleted file mode 100644 index 45ebb12351..0000000000 --- a/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form-view-model.ts +++ /dev/null @@ -1,379 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import * as _ from "lodash"; -import {ArtifactModel, Resource, Component} from "app/models"; -import {ArtifactsUtils, FormState, ValidationUtils, ArtifactType} from "app/utils"; -import {CacheService} from "app/services"; - -export interface IEditArtifactModel { - artifactResource:ArtifactModel; - artifactTypes:Array; - artifactFile:any; -} - -export interface IArtifactResourceFormViewModelScope extends ng.IScope { - forms:any; - $$childTail:any; - isNew:boolean; - isLoading:boolean; - validationPattern:RegExp; - urlValidationPattern:RegExp; - labelValidationPattern:RegExp; - integerValidationPattern:RegExp; - commentValidationPattern:RegExp; - artifactType:string; - editArtifactResourceModel:IEditArtifactModel; - defaultHeatTimeout:number; - validExtensions:any; - originalArtifactName:string; - editForm:ng.IFormController; - footerButtons:Array; - modalInstanceArtifact:ng.ui.bootstrap.IModalServiceInstance; - - fileExtensions():string; - save(doNotCloseModal?:boolean):void; - saveAndAnother():void; - close():void; - getOptions():Array; - isDeploymentHeat():boolean; - onFileChange():void; - setDefaultTimeout():void; - openEditEnvParametersModal(artifact:ArtifactModel):void; - getFormTitle():string; - fileUploadRequired():string; - isArtifactOwner():boolean; -} - -export class ArtifactResourceFormViewModel { - - static '$inject' = [ - '$scope', - '$uibModalInstance', - 'artifact', - 'Sdc.Services.CacheService', - 'ValidationPattern', - 'UrlValidationPattern', - 'LabelValidationPattern', - 'IntegerValidationPattern', - 'CommentValidationPattern', - 'ValidationUtils', - '$base64', - '$state', - 'ArtifactsUtils', - '$uibModal', - 'component' - ]; - - private formState:FormState; - private entityId:string; - - constructor(private $scope:IArtifactResourceFormViewModelScope, - private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance, - private artifact:ArtifactModel, - private cacheService:CacheService, - private ValidationPattern:RegExp, - private UrlValidationPattern:RegExp, - private LabelValidationPattern:RegExp, - private IntegerValidationPattern:RegExp, - private CommentValidationPattern:RegExp, - private ValidationUtils:ValidationUtils, - private $base64:any, - private $state:any, - private artifactsUtils:ArtifactsUtils, - private $uibModal:ng.ui.bootstrap.IModalService, - private component:Component) { - - - this.entityId = this.component.uniqueId; - this.formState = angular.isDefined(artifact.artifactLabel) ? FormState.UPDATE : FormState.CREATE; - this.initScope(); - } - - private initEntity = ():void => { - this.$scope.editArtifactResourceModel.artifactResource = this.artifact; - this.$scope.originalArtifactName = this.artifact.artifactName; - }; - - - private initFooterButtons = ():void => { - - this.$scope.footerButtons = [ - {'name': 'Done', 'css': 'blue', 'callback': this.$scope.save} - ]; - if (this.$scope.isNew) { - this.$scope.footerButtons.push({ - 'name': 'Add Another', - 'css': 'grey', - 'disabled': !this.$scope.isNew && 'deployment' === this.$scope.artifactType, - 'callback': this.$scope.saveAndAnother - }); - } - }; - - private filterDeploymentArtifactTypeByResourceType = (resourceType:string):any => { - let result = {}; - _.each(this.$scope.validExtensions, function (typeSettings:any, typeName:string) { - if (!typeSettings.validForResourceTypes || typeSettings.validForResourceTypes.indexOf(resourceType) > -1) { - result[typeName] = typeSettings; - } - }); - - return result; - }; - - private initArtifactTypes = ():void => { - - let artifactTypes:any = this.cacheService.get('UIConfiguration'); - - if ('deployment' === this.$scope.artifactType) { - - - if ('HEAT_ENV' == this.artifact.artifactType || this.component.selectedInstance) { - this.$scope.validExtensions = artifactTypes.artifacts.deployment.resourceInstanceDeploymentArtifacts; - } else if (this.component.isResource()) { - this.$scope.validExtensions = artifactTypes.artifacts.deployment.resourceDeploymentArtifacts; - this.$scope.validExtensions = this.filterDeploymentArtifactTypeByResourceType((this.component).resourceType); - } else { - this.$scope.validExtensions = artifactTypes.artifacts.deployment.serviceDeploymentArtifacts; - } - - if (this.$scope.validExtensions) { - this.$scope.editArtifactResourceModel.artifactTypes = Object.keys(this.$scope.validExtensions); - } - this.$scope.defaultHeatTimeout = artifactTypes.defaultHeatTimeout; - if (this.$scope.isNew) { - let isHeat = 'HEAT_ENV' == this.artifact.artifactType; - _.remove(this.$scope.editArtifactResourceModel.artifactTypes, (item:string)=> { - return 'HEAT' == item.substring(0, 4) || (!isHeat && item == "VF_MODULES_METADATA") || - _.has(ArtifactType.THIRD_PARTY_RESERVED_TYPES, item); - }); - } - - } - if (this.$scope.artifactType === 'informational') { - this.$scope.editArtifactResourceModel.artifactTypes = artifactTypes.artifacts.other.map((element:any)=> { - return element.name; - }); - _.remove(this.$scope.editArtifactResourceModel.artifactTypes, (item:string)=> { - return _.has(ArtifactType.THIRD_PARTY_RESERVED_TYPES, item) || - _.has(ArtifactType.TOSCA, item); - }) - } - - if (this.component.isResource() && (this.component).isCsarComponent()) { - _.remove(this.$scope.editArtifactResourceModel.artifactTypes, (item:string) => { - return this.artifactsUtils.isLicenseType(item); - }) - } - - }; - - private initEditArtifactResourceModel = ():void => { - this.$scope.editArtifactResourceModel = { - artifactResource: null, - artifactTypes: null, - artifactFile: {} - }; - - this.initEntity(); - }; - - private initScope = ():void => { - - this.$scope.validationPattern = this.ValidationPattern; - this.$scope.urlValidationPattern = this.UrlValidationPattern; - this.$scope.labelValidationPattern = this.LabelValidationPattern; - this.$scope.integerValidationPattern = this.IntegerValidationPattern; - this.$scope.commentValidationPattern = this.CommentValidationPattern; - this.$scope.isLoading = false; - this.$scope.isNew = (this.formState === FormState.CREATE); - this.$scope.artifactType = this.artifactsUtils.getArtifactTypeByState(this.$state.current.name); - this.$scope.modalInstanceArtifact = this.$uibModalInstance; - - this.initEditArtifactResourceModel(); - this.initArtifactTypes(); - - // In case of edit, show the file name in browse. - if (this.artifact.artifactName !== "" && 'HEAT_ENV' !== this.artifact.artifactType) { - this.$scope.editArtifactResourceModel.artifactFile = {}; - this.$scope.editArtifactResourceModel.artifactFile.filename = this.artifact.artifactName; - } - - //scope methods - this.$scope.isDeploymentHeat = ():boolean => { - return !this.$scope.isNew && this.$scope.artifactType === 'deployment' - && this.$scope.editArtifactResourceModel.artifactResource.isHEAT(); - - }; - this.$scope.onFileChange = ():void => { - if (this.$scope.editArtifactResourceModel.artifactFile && this.$scope.editArtifactResourceModel.artifactFile.filename) { - this.$scope.editArtifactResourceModel.artifactResource.artifactName = this.$scope.editArtifactResourceModel.artifactFile.filename; - } else { - this.$scope.editArtifactResourceModel.artifactResource.artifactName = this.$scope.originalArtifactName; - } - }; - this.$scope.setDefaultTimeout = ():void => { - if (this.$scope.isDeploymentHeat() && !this.$scope.editArtifactResourceModel.artifactResource.timeout) { - this.$scope.editArtifactResourceModel.artifactResource.timeout = this.$scope.defaultHeatTimeout; - } - - if (this.$scope.editArtifactResourceModel.artifactFile && this.$scope.editArtifactResourceModel.artifactFile.filename) { - this.$scope.editArtifactResourceModel.artifactFile = {}; - this.$scope.forms.editForm.myArtifactFile.$setValidity('required', false); - } - }; - - this.$scope.fileExtensions = ():string => { - let type:string = this.$scope.editArtifactResourceModel.artifactResource.artifactType; - return type && this.$scope.validExtensions && this.$scope.validExtensions[type].acceptedTypes ? - this.$scope.validExtensions[type].acceptedTypes.join(',') : ""; - }; - - this.$scope.save = (doNotCloseModal?:boolean):void => { - this.$scope.isLoading = true; - this.$scope.editArtifactResourceModel.artifactResource.description = this.ValidationUtils.stripAndSanitize(this.$scope.editArtifactResourceModel.artifactResource.description); - - if (!this.$scope.isDeploymentHeat()) { - this.$scope.editArtifactResourceModel.artifactResource.timeout = null; - } - - if (this.$scope.editArtifactResourceModel.artifactFile) { - this.$scope.editArtifactResourceModel.artifactResource.payloadData = this.$scope.editArtifactResourceModel.artifactFile.base64; - this.$scope.editArtifactResourceModel.artifactResource.artifactName = this.$scope.editArtifactResourceModel.artifactFile.filename; - } - - let onFaild = (response):void => { - this.$scope.isLoading = false; - console.info('onFaild', response); - }; - - let onSuccess = (artifactResource:ArtifactModel):void => { - this.$scope.isLoading = false; - this.$scope.originalArtifactName = ""; - - if (this.$scope.isDeploymentHeat()) { - if (artifactResource.heatParameters) { - this.$scope.openEditEnvParametersModal(artifactResource); - } - } - - if (!doNotCloseModal) { - this.$uibModalInstance.close(); - } else { - this.$scope.editArtifactResourceModel.artifactFile = null; - angular.element("input[type='file']").val(null); // for support chrome when upload the same file - this.artifactsUtils.addAnotherAfterSave(this.$scope); - } - - }; - - if ('HEAT_ENV' == this.artifact.artifactType) { - if (this.component.selectedInstance) { - this.component.uploadInstanceEnvFile(this.$scope.editArtifactResourceModel.artifactResource).then(onSuccess, onFaild); - } else { - this.component.addOrUpdateArtifact(this.$scope.editArtifactResourceModel.artifactResource).then(onSuccess, onFaild); - - } - } else if (this.$scope.isArtifactOwner()) { - this.component.addOrUpdateInstanceArtifact(this.$scope.editArtifactResourceModel.artifactResource).then(onSuccess, onFaild); - } else { - this.component.addOrUpdateArtifact(this.$scope.editArtifactResourceModel.artifactResource).then(onSuccess, onFaild); - } - }; - - this.$scope.isArtifactOwner = ():boolean=> { - return this.component.isService() && !!this.component.selectedInstance; - }; - - this.$scope.saveAndAnother = ():void => { - this.$scope.save(true); - }; - - this.$scope.close = ():void => { - this.$uibModalInstance.close(); - }; - - this.$scope.fileUploadRequired = ():string => { - if (this.$scope.editArtifactResourceModel.artifactFile.filename) { - // This is edit mode - return 'false'; - } else { - return 'true'; - } - }; - - this.$scope.getFormTitle = ():string => { - if ('HEAT_ENV' == this.artifact.artifactType) { - return 'Update HEAT ENV'; - } - if (this.$scope.isDeploymentHeat()) { - if (!this.$scope.editArtifactResourceModel.artifactResource.artifactChecksum) { - return 'Add HEAT Template'; - } - return 'Update HEAT Template'; - } - if (this.$scope.isNew) { - return 'Add Artifact'; - } - return 'Update Artifact'; - }; - - this.$scope.openEditEnvParametersModal = (artifactResource:ArtifactModel):void => { - - let modalOptions:ng.ui.bootstrap.IModalSettings = { - templateUrl: '../env-parameters-form/env-parameters-form.html', - controller: 'Sdc.ViewModels.EnvParametersFormViewModel', - size: 'sdc-md', - backdrop: 'static', - resolve: { - artifact: ():ArtifactModel => { - return artifactResource; - }, - component: ():Component => { - return this.component; - } - } - }; - - let modalInstance:ng.ui.bootstrap.IModalServiceInstance = this.$uibModal.open(modalOptions); - modalInstance - .result - .then(():void => { - }); - }; - - this.$scope.forms = {}; - - this.initFooterButtons(); - - - this.$scope.$watch("forms.editForm.$invalid", (newVal, oldVal) => { - if(this.$scope.forms.editForm) { - this.$scope.footerButtons[0].disabled = this.$scope.forms.editForm.$invalid; - if (this.$scope.isNew) { - this.$scope.footerButtons[1].disabled = this.$scope.forms.editForm.$invalid; - } - } - }); - - } -} diff --git a/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form-view.html b/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form-view.html deleted file mode 100644 index 61ebcc8a28..0000000000 --- a/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form-view.html +++ /dev/null @@ -1,185 +0,0 @@ - - - - - - -
    -
    - - -
    - - - -
    - - - - -
    -
    - - -
    - -
    - -
    - - - -
    - - - -
    - -
    - -
    - - - -
    - -
    - -
    - -
    - - - -
    - - - -
    - -
    - -
    - -
    - -
    - - - -
    - - - -
    - -
    - -
    - -
    - -
    - - - -
    - - - -
    - -
    - UUID -
    - Version -
    -
    - -
    - -
    - - - -
    -
    -
    - diff --git a/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form.less b/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form.less deleted file mode 100644 index 1f77958c88..0000000000 --- a/catalog-ui/src/app/view-models/forms/artifact-form/artifact-form.less +++ /dev/null @@ -1,44 +0,0 @@ -.sdc-edit-artifact-form-container { - - .w-sdc-form-note { - .h_9; - display: block; - position: relative; - top: 13px; - } - - .i-sdc-form-textarea{ - min-height: 95px; - } - - .i-sdc-form-url { - padding-bottom: 0px; - } - - &.mandatory-artifact { - .w-sdc-form-column { - width: 100%; - padding: 0; - min-height: initial; - } - } - .w-sdc-form .i-sdc-form-item.upload input[type="file"] { - display: none - } - - .artifact-info { - text-align: left; - color: rgb(140, 140, 140); - font-size: 13px; - margin-top: -10px; - margin-bottom: 5px; - width: 100%; - min-height: initial; - - span { - color: #666666; - padding-left: 4px; - } - } - -} diff --git a/catalog-ui/src/app/view-models/forms/attribute-form/attribute-form-view.html b/catalog-ui/src/app/view-models/forms/attribute-form/attribute-form-view.html deleted file mode 100644 index 902d564935..0000000000 --- a/catalog-ui/src/app/view-models/forms/attribute-form/attribute-form-view.html +++ /dev/null @@ -1,168 +0,0 @@ - - - - -
    -
    - -
    - -
    - - -
    - - -
    - - - - -
    -
    - - -
    - - -
    - - - -
    -
    - - -
    - -
    - -
    - - -
    - -
    -
    - - -
    - - - -
    - -
    -
    - - -
    - - - -
    - - - - -
    -
    - - -
    - - -
    -
    - -
    - -
    -
    - -
    diff --git a/catalog-ui/src/app/view-models/forms/attribute-form/attribute-from-view-model.ts b/catalog-ui/src/app/view-models/forms/attribute-form/attribute-from-view-model.ts deleted file mode 100644 index 0e4a851aa6..0000000000 --- a/catalog-ui/src/app/view-models/forms/attribute-form/attribute-from-view-model.ts +++ /dev/null @@ -1,262 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import * as _ from "lodash"; -import {AttributeModel, Component} from "app/models"; -import {IMapRegex, ValidationUtils, FormState, PROPERTY_TYPES} from "app/utils"; - -export interface IEditAttributeModel { - attribute:AttributeModel; - types:Array; - simpleTypes:Array; -} - -export class attributeValue {//in order to solve DE226783, we update the value on another obj - value:string; -} - -interface IAttributeFormViewModelScope extends ng.IScope { - $$childTail:any; - forms:any; - editForm:ng.IFormController; - footerButtons:Array; - isService:boolean; - editAttributeModel:IEditAttributeModel; - modalInstanceAttribute:ng.ui.bootstrap.IModalServiceInstance; - isNew:boolean; - listRegex:IMapRegex; - mapRegex:IMapRegex; - propertyNameValidationPattern:RegExp; - commentValidationPattern:RegExp; - isLoading:boolean; - validationPattern:RegExp; - attributeValue:attributeValue; - - save():void; - close():void; - onTypeChange():void; - onValueChange():void; - isAttributeValueOwner():boolean; - validateIntRange(value:string):boolean; - validateUniqueKeys(viewValue:string):boolean; - getValidationTranslate():string; - showSchema():boolean; - isSchemaEditable():boolean; - validateName():void; -} - -export class AttributeFormViewModel { - - static '$inject' = [ - '$scope', - '$uibModalInstance', - 'attribute', - 'ValidationUtils', - 'CommentValidationPattern', - 'PropertyNameValidationPattern', - 'component' - ]; - - private formState:FormState; - - - constructor(private $scope:IAttributeFormViewModelScope, - private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance, - private attribute:AttributeModel, - private ValidationUtils:ValidationUtils, - private CommentValidationPattern:RegExp, - private PropertyNameValidationPattern:RegExp, - private component:Component) { - this.formState = angular.isDefined(attribute.name) ? FormState.UPDATE : FormState.CREATE; - this.initScope(); - } - - private initResource = ():void => { - this.$scope.editAttributeModel.attribute = new AttributeModel(this.attribute); - if (this.$scope.editAttributeModel.types.indexOf(this.attribute.type) === -1) {//attribute defaulte type is string too? - this.attribute.type = "string"; - } - }; - - private initEditAttributeModel = ():void => { - this.$scope.editAttributeModel = { - attribute: null, - types: ['integer', 'string', 'float', 'boolean', 'list', 'map'], - simpleTypes: ['integer', 'string', 'float', 'boolean'] - }; - - this.initResource(); - }; - - private initScope = ():void => { - - //scope attributes - this.$scope.forms = {}; - this.$scope.propertyNameValidationPattern = this.PropertyNameValidationPattern; - this.$scope.commentValidationPattern = this.CommentValidationPattern; - - this.$scope.modalInstanceAttribute = this.$uibModalInstance; - this.$scope.listRegex = this.ValidationUtils.getPropertyListPatterns(); - this.$scope.mapRegex = this.ValidationUtils.getPropertyMapPatterns(); - - this.$scope.isNew = (this.formState === FormState.CREATE); - this.$scope.isLoading = false; - this.$scope.attributeValue = new attributeValue(); - - this.initEditAttributeModel(); - this.setValidationPattern(); - - //scope methods - this.$scope.save = ():void => { - if (!this.$scope.forms.editForm.$invalid) { - let attribute:AttributeModel = this.$scope.editAttributeModel.attribute; - this.$scope.editAttributeModel.attribute.description = this.ValidationUtils.stripAndSanitize(this.$scope.editAttributeModel.attribute.description); - ////if read only - just closes the modal - if (this.$scope.editAttributeModel.attribute.readonly && !this.$scope.isAttributeValueOwner()) { - this.$uibModalInstance.close(); - return; - } - this.$scope.isLoading = true; - let onAttributeFaild = (response):void => { - console.info('onFaild', response); - this.$scope.isLoading = false; - }; - - let onAttributeSuccess = (attributeFromBE:AttributeModel):void => { - console.info('onAttributeResourceSuccess : ', attributeFromBE); - this.$scope.isLoading = false; - this.$uibModalInstance.close(); - }; - - //in case we have uniqueId we call update method - if (this.$scope.isAttributeValueOwner()) { - attribute.value = this.$scope.attributeValue.value; - this.component.updateInstanceAttribute(attribute).then(onAttributeSuccess, onAttributeFaild); - } else { - attribute.defaultValue = this.$scope.attributeValue.value; - this.component.addOrUpdateAttribute(attribute).then(onAttributeSuccess, onAttributeFaild); - } - } - }; - - this.$scope.close = ():void => { - this.$uibModalInstance.close(); - }; - - this.$scope.validateName = ():void => { - let existsAttr:AttributeModel = _.find(this.component.attributes, (attribute:AttributeModel) => { - return attribute.name === this.$scope.editAttributeModel.attribute.name; - }); - if (existsAttr) { - this.$scope.forms.editForm["attributeName"].$setValidity('nameExist', false); - } else { - this.$scope.forms.editForm["attributeName"].$setValidity('nameExist', true); - } - - }; - - this.$scope.onTypeChange = ():void => { - this.$scope.editAttributeModel.attribute.value = ''; - this.$scope.editAttributeModel.attribute.defaultValue = ''; - this.setValidationPattern(); - }; - - this.$scope.isAttributeValueOwner = ():boolean=> { - return this.component.isService() || !!this.component.selectedInstance; - }; - - this.$scope.onValueChange = ():void => { - if (!this.$scope.editAttributeModel.attribute.value) { - if (this.$scope.isAttributeValueOwner()) { - this.$scope.editAttributeModel.attribute.value = this.$scope.editAttributeModel.attribute.defaultValue; - } - } - }; - - - this.$scope.validateUniqueKeys = (viewValue:string):boolean => { - if (this.$scope.editAttributeModel.attribute.type === 'map') { - return this.ValidationUtils.validateUniqueKeys(viewValue); - } - else { - return true; //always valid if not a map - } - }; - - this.$scope.validateIntRange = (value:string):boolean => { - return !value || this.ValidationUtils.validateIntRange(value); - }; - - this.$scope.isSchemaEditable = ():boolean => { - let schemaType = this.$scope.editAttributeModel.attribute.schema.property.type; - return this.$scope.editAttributeModel.simpleTypes.indexOf(schemaType) > -1 || !schemaType; - }; - - this.$scope.showSchema = ():boolean => { - return ['list', 'map'].indexOf(this.$scope.editAttributeModel.attribute.type) > -1; - }; - - this.$scope.getValidationTranslate = ():string => { - let result = "ATTRIBUTE_EDIT_PATTERN"; - if (this.$scope.showSchema()) { - - result = "ATTRIBUTE_EDIT_" + this.$scope.editAttributeModel.attribute.type.toUpperCase(); - - if (this.$scope.editAttributeModel.attribute.schema.property.type === PROPERTY_TYPES.STRING) { - result += "_STRING"; - } else if (this.$scope.editAttributeModel.attribute.schema.property.type === PROPERTY_TYPES.BOOLEAN) { - result += "_BOOLEAN"; - } else { - result += "_GENERIC"; - } - } - - return result; - }; - - // Add the done button at the footer. - this.$scope.footerButtons = [ - {'name': 'Done', 'css': 'blue', 'callback': this.$scope.save}, - {'name': 'Cancel', 'css': 'grey', 'callback': this.$scope.close} - ]; - - this.$scope.$watchCollection("forms.editForm.$invalid", (newVal, oldVal) => { - this.$scope.footerButtons[0].disabled = this.$scope.forms.editForm.$invalid; - }); - - this.$scope.attributeValue.value = this.$scope.isAttributeValueOwner() ? this.$scope.editAttributeModel.attribute.value : this.$scope.editAttributeModel.attribute.defaultValue; - }; - - - private setValidationPattern = ():void => { - - if (this.$scope.editAttributeModel.attribute.type === 'list') { - this.$scope.validationPattern = this.$scope.listRegex[this.$scope.editAttributeModel.attribute.schema.property.type]; - } - else if (this.$scope.editAttributeModel.attribute.type === 'map') { - this.$scope.validationPattern = this.$scope.mapRegex[this.$scope.editAttributeModel.attribute.schema.property.type]; - } - else { - this.$scope.validationPattern = this.ValidationUtils.getValidationPattern(this.$scope.editAttributeModel.attribute.type); - } - - }; -} diff --git a/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.html b/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.html deleted file mode 100644 index b3d64818ba..0000000000 --- a/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.html +++ /dev/null @@ -1,108 +0,0 @@ - - - -
    - -
    -
    -
    -
    - - {{header.title}} -
    -
    -
    - - -
    -
    - {{parameter.name}} - -
    - -
    - {{parameter.defaultValue}} -
    - - - - - -
    - -
    - * -
    - - -
    -
    -
    -
    -
    -
    -
    -
    - - - -
    -
    - -
    - -
    -
    - -
    -
    -
    -
    -
    -
    - diff --git a/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.less b/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.less deleted file mode 100644 index d89ab37030..0000000000 --- a/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.less +++ /dev/null @@ -1,177 +0,0 @@ -.sdc-env-form-container{ - .w-sdc-modal-body{ - padding: 20px 10px 2px 10px; - } - .w-sdc-modal-body-content{ - .b_6; - display: block; - } - - .env-file-generation-label{ - .p_9; - .bold; - margin-bottom: 20px; - } -} - -.w-sdc-env-form-container { - height: 650px; - - .w-sdc-env-search { - padding: 10px 20px 20px 0; - white-space: nowrap; - position: relative; - width: 60%; - height: 64px; - - .env-search-icon { - top: 9px; - right: 11px; - } - - .magnification-white { - .sprite-new; - .search-white-icon; - .hand; - } - - .search-icon-container { - width: 35px; - height: 30px; - background-color: @main_color_a; - white-space: nowrap; - float: right; - position: relative; - bottom: 31px; - right: 1px; - border-radius: 0px 4px 4px 0px; - .hand - } - - .w-sdc-env-search-input { - border: 1px solid @color_e; - .border-radius(4px); - height: 32px; - margin: 0; - padding: 0px 28px 3px 10px; - vertical-align: 4px; - width: 100%; - outline: none; - font-style: italic; - } - } - - .table-container-flex { - height: 570px; - - .table { - height: 100%; - .flex-item:nth-child(1) { - flex-grow: 20; - .show-desc{ - float: right; - top: 10px; - position: relative; - } - } - - .flex-item:nth-child(2) { - flex-grow: 10; - } - - .flex-item:nth-child(3) { - flex-grow: 10; - } - .scrollbar-container{ - max-height: 527px; - } - .left-column-container{ - .required-symbol { - .m_14_m; - color: #f33; - display: none; - position: relative; - left: -4px; - top: 3px; - } - - .i-sdc-form-item{ - border-right: none; - margin: 0px; - - .input-parameter{ - border: none; - height: 30px; - width: 254px; - float: right; - input{ - .m_13_m; - width: 100%; - display: inline-flex; - padding-right: 33px; - } - .action-button{ - border-left: solid 1px @main_color_o; - position: relative; - height: 20px; - width: 25px; - top: -25px; - left: 228px; - padding-left: 6px; - background-color: @main_color_p; - div:not(.disable){ - .hand; - } - } - } - - &.required{ - .required-symbol { - display: inline-flex; - } - .input-parameter { - width: 250px; - } - .action-button{ - left: 224px; - } - } - } - - - - } - } - - .text{ - overflow: hidden; - text-overflow: ellipsis; - display: inline-block; - white-space: nowrap; - } - } - - - .parameter-description{ - background-color: @func_color_r; - border-left: 4px solid @main_color_a; - padding: 10px 30px; - } -} - -.header-info{ - float: right; -} - -.parameter-description-popover{ - z-index: 1100; - min-width: 210px; - .arrow{ - left: 20px !important; - border-width: 7px; - bottom: -8px !important; - } - .popover-content{ - .f-type._13_m;; - } -} diff --git a/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.ts b/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.ts deleted file mode 100644 index a30fd15c63..0000000000 --- a/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parameters-form.ts +++ /dev/null @@ -1,184 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {ValidationUtils} from "app/utils"; -import {ArtifactModel, HeatParameterModel, Component} from "app/models"; - -export interface IEnvParametersFormViewModelScope extends ng.IScope { - isLoading:boolean; - type:string; - heatParameters:Array; - forms:any; - artifactResource:ArtifactModel; - buttons:Array; - envParametersModal:ng.ui.bootstrap.IModalServiceInstance; - tableHeadersList:Array; - selectedParameter:HeatParameterModel; - templatePopover:string; - - getValidationPattern(type:string):RegExp; - isInstance():boolean; - validateJson(json:string):boolean; - onValueChanged(parameter: HeatParameterModel):void; - close():void; - save():void; - openDescPopover(selectedParam:HeatParameterModel):void; - closeDescriptionPopover():void; -} - -export class EnvParametersFormViewModel { - - static '$inject' = [ - '$scope', - '$templateCache', - '$state', - '$uibModalInstance', - 'artifact', - 'ValidationUtils', - 'component' - ]; - - constructor(private $scope:IEnvParametersFormViewModelScope, - private $templateCache:ng.ITemplateCacheService, - private $state:any, - private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance, - private artifact:ArtifactModel, - private ValidationUtils:ValidationUtils, - private component:Component) { - - - this.initScope(); - } - - private updateInstanceHeat = ():void => { - let success = (responseArtifact:ArtifactModel):void => { - this.$scope.isLoading = false; - this.$uibModalInstance.close(); - }; - - let error = ():void => { - this.$scope.isLoading = false; - console.info('Failed to load save artifact'); - }; - - this.component.addOrUpdateInstanceArtifact(this.$scope.artifactResource).then(success, error); - }; - - private initScope = ():void => { - this.$scope.forms = {}; - this.$scope.envParametersModal = this.$uibModalInstance; - this.$scope.artifactResource = this.artifact; - this.$scope.heatParameters = angular.copy(this.artifact.heatParameters); - //if param does not have a value - display the default - this.$scope.heatParameters.forEach((heatParam) => { - heatParam.currentValue = heatParam.currentValue || heatParam.defaultValue; - }); - this.$scope.tableHeadersList = [ - {title: "Parameter", property: "name"}, - {title: "Default Value", property: "defaultValue", info: "DEFAULT_VALUE_INFO"}, - {title: "Current Value", property: "currentValue", info: "CURRENT_VALUE_INFO"} - ]; - - this.$templateCache.put("env-parametr-description-popover.html", require('app/view-models/forms/env-parameters-form/env-parametr-description-popover.html')); - this.$scope.templatePopover = "env-parametr-description-popover.html"; - - this.$scope.getValidationPattern = (validationType:string, parameterType?:string):RegExp => { - return this.ValidationUtils.getValidationPattern(validationType, parameterType); - }; - - this.$scope.validateJson = (json:string):boolean => { - if (!json) { - return true; - } - return this.ValidationUtils.validateJson(json); - }; - - this.$scope.isInstance = ():boolean => { - return !!this.component.selectedInstance; - }; - - this.$scope.save = ():void => { - this.$scope.buttons[0].disabled = true;//prevent double click (DE246266) - this.$scope.isLoading = true; - this.artifact.heatParameters = angular.copy(this.$scope.heatParameters); - this.artifact.heatParameters.forEach((parameter:any):void => { - if ("" === parameter.currentValue) { - //[Bug 154465] - Update and erase current value field in Env parameters form return empty String ("") instead of null. - parameter.currentValue = null; - } else if (parameter.defaultValue && parameter.defaultValue == parameter.currentValue) { - parameter.currentValue = undefined; - } - }); - - if (this.$scope.isInstance()) { - this.updateInstanceHeat(); - return; - } - - let success = (responseArtifact:ArtifactModel):void => { - this.$scope.isLoading = false; - this.$uibModalInstance.close(); - - }; - - let error = ():void => { - this.$scope.isLoading = false; - console.info('Failed to load save artifact'); - }; - - this.component.addOrUpdateArtifact(this.$scope.artifactResource).then(success, error); - }; - - this.$scope.onValueChanged = (parameter: HeatParameterModel):void => { - parameter.filterTerm = parameter.name + ' ' + parameter.currentValue + ' ' + parameter.defaultValue + ' ' +parameter.description - if('json'==parameter.type){ - this.$scope.forms.editForm[parameter.name].$setValidity('pattern', this.$scope.validateJson(parameter.currentValue)); - } - } - - this.$scope.close = ():void => { - //this.artifact.heatParameters.forEach((parameter:any):void => { - // if (!parameter.currentValue && parameter.defaultValue) { - // parameter.currentValue = parameter.defaultValue; - // } - //}); - this.$uibModalInstance.dismiss(); - }; - - this.$scope.openDescPopover = (selectedParam:HeatParameterModel):void => { - this.$scope.selectedParameter = selectedParam; - }; - - this.$scope.closeDescriptionPopover = ():void => { - this.$scope.selectedParameter = null; - }; - - this.$scope.buttons = [ - {'name': 'Save', 'css': 'blue', 'callback': this.$scope.save}, - {'name': 'Cancel', 'css': 'grey', 'callback': this.$scope.close} - ]; - - this.$scope.$watch("forms.editForm.$invalid", (newVal, oldVal) => { - this.$scope.buttons[0].disabled = this.$scope.forms.editForm.$invalid; - }); - - }; -} diff --git a/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parametr-description-popover.html b/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parametr-description-popover.html deleted file mode 100644 index 6db354a072..0000000000 --- a/catalog-ui/src/app/view-models/forms/env-parameters-form/env-parametr-description-popover.html +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - - {{selectedParameter.description}} -
    diff --git a/catalog-ui/src/app/view-models/forms/input-form/input-form-view-modal.ts b/catalog-ui/src/app/view-models/forms/input-form/input-form-view-modal.ts deleted file mode 100644 index 56542b9694..0000000000 --- a/catalog-ui/src/app/view-models/forms/input-form/input-form-view-modal.ts +++ /dev/null @@ -1,146 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {FormState, PROPERTY_TYPES, ValidationUtils, PROPERTY_VALUE_CONSTRAINTS} from "app/utils"; -import {InputModel} from "app/models"; - -export interface IInputEditModel { - editInput:InputModel; -} - -export interface IInputFormViewModelScope extends ng.IScope { - forms:any; - editForm:ng.IFormController; - footerButtons:Array; - isService:boolean; - modalInstanceInput:ng.ui.bootstrap.IModalServiceInstance; - isLoading:boolean; - inputEditModel:IInputEditModel; - myValue:any; - maxLength:number; - - save():void; - close():void; - validateIntRange(value:string):boolean; - validateJson(json:string):boolean; - getValidationPattern(type:string):RegExp; - showSchema():boolean; -} - -export class InputFormViewModel { - - static '$inject' = [ - '$scope', - '$uibModalInstance', - 'ValidationUtils', - 'input' - ]; - - private formState:FormState; - - - constructor(private $scope:IInputFormViewModelScope, - private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance, - private ValidationUtils:ValidationUtils, - private input:InputModel) { - this.initScope(); - this.initMyValue(); - } - - private initMyValue = ():void => { - switch (this.$scope.inputEditModel.editInput.type) { - case PROPERTY_TYPES.MAP: - this.$scope.myValue = this.$scope.inputEditModel.editInput.defaultValue ? JSON.parse(this.$scope.inputEditModel.editInput.defaultValue) : {'': null}; - break; - case PROPERTY_TYPES.LIST: - this.$scope.myValue = this.$scope.inputEditModel.editInput.defaultValue ? JSON.parse(this.$scope.inputEditModel.editInput.defaultValue) : []; - break; - } - }; - - private initDefaultValueMaxLength = ():void => { - switch (this.$scope.inputEditModel.editInput.type) { - case PROPERTY_TYPES.MAP: - case PROPERTY_TYPES.LIST: - this.$scope.maxLength = this.$scope.inputEditModel.editInput.schema.property.type == PROPERTY_TYPES.JSON ? - PROPERTY_VALUE_CONSTRAINTS.JSON_MAX_LENGTH : - PROPERTY_VALUE_CONSTRAINTS.MAX_LENGTH; - break; - case PROPERTY_TYPES.JSON: - this.$scope.maxLength = PROPERTY_VALUE_CONSTRAINTS.JSON_MAX_LENGTH; - break; - default: - this.$scope.maxLength = PROPERTY_VALUE_CONSTRAINTS.MAX_LENGTH; - } - }; - - private initScope = ():void => { - this.$scope.forms = {}; - this.$scope.modalInstanceInput = this.$uibModalInstance; - this.$scope.inputEditModel = { - editInput: null - }; - this.$scope.inputEditModel.editInput = this.input; - this.initDefaultValueMaxLength(); - - //scope methods - this.$scope.save = ():void => { - if (this.$scope.showSchema()) { - this.$scope.inputEditModel.editInput.defaultValue = JSON.stringify(this.$scope.myValue); - } - }; - - this.$scope.close = ():void => { - this.$uibModalInstance.close(); - }; - - this.$scope.validateIntRange = (value:string):boolean => { - return !value || this.ValidationUtils.validateIntRange(value); - }; - - this.$scope.validateJson = (json:string):boolean => { - if (!json) { - return true; - } - return this.ValidationUtils.validateJson(json); - }; - - this.$scope.showSchema = ():boolean => { - return ['list', 'map'].indexOf(this.$scope.inputEditModel.editInput.type) > -1; - }; - - this.$scope.getValidationPattern = (type:string):RegExp => { - return this.ValidationUtils.getValidationPattern(type); - }; - - // Add the done button at the footer. - this.$scope.footerButtons = [ - {'name': 'Done', 'css': 'blue', 'callback': this.$scope.save}, - {'name': 'Cancel', 'css': 'grey', 'callback': this.$scope.close} - ]; - - this.$scope.$watchCollection("forms.editForm.$invalid", (newVal, oldVal) => { - this.$scope.footerButtons[0].disabled = this.$scope.forms.editForm.$invalid; - }); - - }; -} - diff --git a/catalog-ui/src/app/view-models/forms/input-form/input-form-view.html b/catalog-ui/src/app/view-models/forms/input-form/input-form-view.html deleted file mode 100644 index 446a926ed4..0000000000 --- a/catalog-ui/src/app/view-models/forms/input-form/input-form-view.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - -
    -
    - -
    - -
    - - -
    - - -
    - - -
    - - -
    - - -
    - -
    - -
    - - -
    - -
    - - -
    - -
    - -
    -
    - -
    -
    - -
    -
    -
    - - - -
    - - -
    -
    -
    -
    -
    - -
    - -
    - -
    -
    - -
    diff --git a/catalog-ui/src/app/view-models/forms/property-forms/base-property-form/property-form-base-view.html b/catalog-ui/src/app/view-models/forms/property-forms/base-property-form/property-form-base-view.html index e2594bc727..ae96b66641 100644 --- a/catalog-ui/src/app/view-models/forms/property-forms/base-property-form/property-form-base-view.html +++ b/catalog-ui/src/app/view-models/forms/property-forms/base-property-form/property-form-base-view.html @@ -13,7 +13,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -
    diff --git a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts index f5c057e41e..37b1ce75a8 100644 --- a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts +++ b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts @@ -20,12 +20,16 @@ 'use strict'; import * as _ from "lodash"; -import { - PROPERTY_TYPES, ModalsHandler, ValidationUtils, PROPERTY_VALUE_CONSTRAINTS, FormState, PROPERTY_DATA} from "app/utils"; -import {DataTypesService} from "app/services"; -import {PropertyModel, DataTypesMap, Component, GroupInstance, PolicyInstance, PropertyBEModel} from "app/models"; -import {ComponentInstance} from "../../../../models/componentsInstances/componentInstance"; +import { PROPERTY_TYPES, ValidationUtils, PROPERTY_VALUE_CONSTRAINTS, FormState, PROPERTY_DATA } from "app/utils"; +import { DataTypesService } from "app/services"; +import { PropertyModel, DataTypesMap, Component, GroupInstance, PolicyInstance, PropertyBEModel, ComponentMetadata } from "app/models"; +import { ComponentInstance } from "../../../../models/componentsInstances/componentInstance"; import { ComponentInstanceServiceNg2 } from "app/ng2/services/component-instance-services/component-instance.service"; +import { SdcUiCommon, SdcUiServices, SdcUiComponents } from "onap-ui-angular"; +import { CompositionService } from "app/ng2/pages/composition/composition.service"; +import { WorkspaceService } from "app/ng2/pages/workspace/workspace.service"; +import { Observable } from "rxjs"; +import { TopologyTemplateService } from "app/ng2/services/component-services/topology-template.service"; export interface IEditPropertyModel { property:PropertyModel; @@ -44,7 +48,7 @@ interface IPropertyFormViewModelScope extends ng.IScope { propertyNameValidationPattern:RegExp; commentValidationPattern:RegExp; editPropertyModel:IEditPropertyModel; - modalInstanceProperty:ng.ui.bootstrap.IModalServiceInstance; + modalInstanceProperty:ng.ui.bootstrap.IModalServiceInstance; currentPropertyIndex:number; isLastProperty:boolean; myValue:any; @@ -54,6 +58,7 @@ interface IPropertyFormViewModelScope extends ng.IScope { maxLength:number; isPropertyValueOwner:boolean; isVnfConfiguration:boolean; + constraints:string[]; validateJson(json:string):boolean; save(doNotCloseModal?:boolean):void; @@ -82,17 +87,20 @@ export class PropertyFormViewModel { 'PropertyNameValidationPattern', 'CommentValidationPattern', 'ValidationUtils', - 'component', + // 'component', '$filter', - 'ModalsHandler', + 'ModalServiceSdcUI', 'filteredProperties', '$timeout', 'isPropertyValueOwner', 'propertyOwnerType', 'propertyOwnerId', - 'ComponentInstanceServiceNg2' + 'ComponentInstanceServiceNg2', + 'TopologyTemplateService', + 'CompositionService', + 'workspaceService' ]; - + private formState:FormState; constructor(private $scope:IPropertyFormViewModelScope, @@ -103,17 +111,21 @@ export class PropertyFormViewModel { private PropertyNameValidationPattern:RegExp, private CommentValidationPattern:RegExp, private ValidationUtils:ValidationUtils, - private component:Component, + // private component:Component, private $filter:ng.IFilterService, - private ModalsHandler:ModalsHandler, + private modalService:SdcUiServices.ModalService, private filteredProperties:Array, private $timeout:ng.ITimeoutService, private isPropertyValueOwner:boolean, private propertyOwnerType:string, private propertyOwnerId:string, - private ComponentInstanceServiceNg2: ComponentInstanceServiceNg2) { + private ComponentInstanceServiceNg2: ComponentInstanceServiceNg2, + private topologyTemplateService: TopologyTemplateService, + private compositionService: CompositionService, + private workspaceService: WorkspaceService) { this.formState = angular.isDefined(property.name) ? FormState.UPDATE : FormState.CREATE; + this.initScope(); } @@ -121,8 +133,10 @@ export class PropertyFormViewModel { this.$scope.editPropertyModel.property = new PropertyModel(this.property); this.$scope.editPropertyModel.property.type = this.property.type ? this.property.type : null; this.$scope.editPropertyModel.property.value = this.$scope.editPropertyModel.property.value || this.$scope.editPropertyModel.property.defaultValue; + this.$scope.constraints = this.property.constraints && this.property.constraints[0] ? this.property.constraints[0]["validValues"] : null; + this.setMaxLength(); - this.initAddOnLabels(); + }; //init property add-ons labels that show up at the left side of the input. @@ -131,23 +145,13 @@ export class PropertyFormViewModel { //the server sends back the normalized name. Remove it (to prevent interference with validation) and set the addon label to the component name directly. //Note: this cant be done in properties.ts because we dont have access to the component if (this.$scope.editPropertyModel.property.value) { - let splitProp = this.$scope.editPropertyModel.property.value.split(new RegExp(this.component.normalizedName + '.', "gi")); + let splitProp = this.$scope.editPropertyModel.property.value.split(new RegExp(this.workspaceService.metadata.normalizedName + '.', "gi")); this.$scope.editPropertyModel.property.value = splitProp.pop(); } - this.$scope.editPropertyModel.property.addOn = this.component.name; + this.$scope.editPropertyModel.property.addOn = this.workspaceService.metadata.name; } } - private initEditPropertyModel = ():void => { - this.$scope.editPropertyModel = { - property: null, - types: PROPERTY_DATA.TYPES, - simpleTypes: PROPERTY_DATA.SIMPLE_TYPES - }; - - this.initResource(); - }; - private initForNotSimpleType = ():void => { let property = this.$scope.editPropertyModel.property; this.$scope.isTypeDataType = this.DataTypesService.isDataTypeForPropertyType(this.$scope.editPropertyModel.property); @@ -195,20 +199,25 @@ export class PropertyFormViewModel { this.$scope.commentValidationPattern = this.CommentValidationPattern; this.$scope.isLoading = false; this.$scope.isNew = (this.formState === FormState.CREATE); - this.$scope.isService = this.component.isService(); + this.$scope.isService = this.workspaceService.metadata.isService(); this.$scope.modalInstanceProperty = this.$uibModalInstance; this.$scope.currentPropertyIndex = _.findIndex(this.filteredProperties, i=> i.name == this.property.name); this.$scope.isLastProperty = this.$scope.currentPropertyIndex == (this.filteredProperties.length - 1); this.$scope.dataTypes = this.DataTypesService.getAllDataTypes(); this.$scope.isPropertyValueOwner = this.isPropertyValueOwner; this.$scope.propertyOwnerType = this.propertyOwnerType; - this.initEditPropertyModel(); + + this.$scope.editPropertyModel = { + property : new PropertyModel(this.property), + types : PROPERTY_DATA.TYPES, + simpleTypes : PROPERTY_DATA.SIMPLE_TYPES}; //All simple types + //check if property of VnfConfiguration this.$scope.isVnfConfiguration = false; - if(this.propertyOwnerType == "component" && angular.isArray(this.component.componentInstances)) { + if(this.propertyOwnerType == "component" && angular.isArray(this.compositionService.componentInstances)) { - var componentPropertyOwner:ComponentInstance = this.component.componentInstances.find((ci:ComponentInstance) => { + var componentPropertyOwner:ComponentInstance = this.compositionService.componentInstances.find((ci:ComponentInstance) => { return ci.uniqueId === this.property.resourceInstanceUniqueId; }); if (componentPropertyOwner && componentPropertyOwner.componentName === 'vnfConfiguration') { @@ -219,6 +228,7 @@ export class PropertyFormViewModel { this.$scope.nonPrimitiveTypes = _.filter(Object.keys(this.$scope.dataTypes), (type:string)=> { return this.$scope.editPropertyModel.types.indexOf(type) == -1; }); + this.initResource(); this.initForNotSimpleType(); @@ -263,10 +273,10 @@ export class PropertyFormViewModel { //Not clean, but doing this as a temporary fix until we update the property right panel modals if(this.propertyOwnerType == "group"){ - this.ComponentInstanceServiceNg2.updateComponentGroupInstanceProperties(this.component, this.propertyOwnerId, [property]) + this.ComponentInstanceServiceNg2.updateComponentGroupInstanceProperties(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, this.propertyOwnerId, [property]) .subscribe((propertiesFromBE) => { onPropertySuccess(propertiesFromBE[0])}, error => onPropertyFaild); } else if(this.propertyOwnerType == "policy"){ - this.ComponentInstanceServiceNg2.updateComponentPolicyInstanceProperties(this.component, this.propertyOwnerId, [property]) + this.ComponentInstanceServiceNg2.updateComponentPolicyInstanceProperties(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, this.propertyOwnerId, [property]) .subscribe((propertiesFromBE) => { onPropertySuccess(propertiesFromBE[0])}, error => onPropertyFaild); } else { //in case we have uniqueId we call update method @@ -275,7 +285,7 @@ export class PropertyFormViewModel { let myValueString:string = JSON.stringify(this.$scope.myValue); property.value = myValueString; } - this.component.updateInstanceProperties(property.resourceInstanceUniqueId, [property]).then((propertiesFromBE) => onPropertySuccess(propertiesFromBE[0]), onPropertyFaild); + this.updateInstanceProperties(property.resourceInstanceUniqueId, [property]).subscribe((propertiesFromBE) => onPropertySuccess(propertiesFromBE[0]), onPropertyFaild); } else { if (!this.$scope.editPropertyModel.property.simpleType && !this.$scope.isSimpleType(property.type)) { let myValueString:string = JSON.stringify(this.$scope.myValue); @@ -283,7 +293,7 @@ export class PropertyFormViewModel { } else { this.$scope.editPropertyModel.property.defaultValue = this.$scope.editPropertyModel.property.value; } - this.component.addOrUpdateProperty(property).then(onPropertySuccess, onPropertyFaild); + this.addOrUpdateProperty(property).subscribe(onPropertySuccess, onPropertyFaild); } } }; @@ -362,14 +372,65 @@ export class PropertyFormViewModel { }; this.$scope.delete = (property:PropertyModel):void => { - let onOk = ():void => { - this.component.deleteProperty(property.uniqueId).then( + let onOk: Function = ():void => { + this.deleteProperty(property.uniqueId).subscribe( this.$scope.close ); }; let title:string = this.$filter('translate')("PROPERTY_VIEW_DELETE_MODAL_TITLE"); let message:string = this.$filter('translate')("PROPERTY_VIEW_DELETE_MODAL_TEXT", "{'name': '" + property.name + "'}"); - this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk); + const okButton = {testId: "OK", text: "OK", type: SdcUiCommon.ButtonType.info, callback: onOk, closeModal: true} as SdcUiComponents.ModalButtonComponent; + this.modalService.openInfoModal(title, message, 'delete-modal', [okButton]); }; } + + private updateInstanceProperties = (componentInstanceId:string, properties:PropertyModel[]):Observable => { + + return this.ComponentInstanceServiceNg2.updateInstanceProperties(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, componentInstanceId, properties) + .map(newProperties => { + newProperties.forEach((newProperty) => { + if(newProperty.path[0] === newProperty.resourceInstanceUniqueId) newProperty.path.shift(); + // find exist instance property in parent component for update the new value ( find bu uniqueId & path) + let existProperty: PropertyModel = _.find(this.compositionService.componentInstancesProperties[newProperty.resourceInstanceUniqueId], { + uniqueId: newProperty.uniqueId, + path: newProperty.path + }); + let index = this.compositionService.componentInstancesProperties[newProperty.resourceInstanceUniqueId].indexOf(existProperty); + this.compositionService.componentInstancesProperties[newProperty.resourceInstanceUniqueId][index] = newProperty; + }); + return newProperties; + }); + }; + + private addOrUpdateProperty = (property:PropertyModel):Observable => { + if (!property.uniqueId) { + let onSuccess = (property:PropertyModel):PropertyModel => { + let newProperty = new PropertyModel(property); + this.filteredProperties.push(newProperty); + return newProperty; + }; + return this.topologyTemplateService.addProperty(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, property).map(onSuccess); + } + else { + let onSuccess = (newProperty:PropertyModel):PropertyModel => { + // find exist instance property in parent component for update the new value ( find bu uniqueId ) + let existProperty:PropertyModel = _.find(this.filteredProperties, {uniqueId: newProperty.uniqueId}); + let propertyIndex = this.filteredProperties.indexOf(existProperty); + this.filteredProperties[propertyIndex] = newProperty; + return newProperty; + }; + return this.topologyTemplateService.updateProperty(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, property).map(onSuccess); + } + }; + + public deleteProperty = (propertyId:string):Observable => { + let onSuccess = ():void => { + console.log("Property deleted"); + delete _.remove(this.filteredProperties, {uniqueId: propertyId})[0]; + }; + let onFailed = ():void => { + console.log("Failed to delete property"); + }; + return this.topologyTemplateService.deleteProperty(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, propertyId).map(onSuccess, onFailed); + }; } diff --git a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html index 1f484160da..7c29d98641 100644 --- a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html +++ b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html @@ -13,7 +13,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -
    @@ -160,8 +159,11 @@ fields-prefix-name="currentPropertyIndex" read-only="(editPropertyModel.property.readonly && !isPropertyValueOwner) || isVnfConfiguration" default-value="{{getDefaultValue()}}" - max-length="maxLength"> + max-length="maxLength" + constraints = "editPropertyModel.property.constraints && editPropertyModel.property.constraints[0].validValues"> +
    +
    + max-length="maxLength" + constraints = "editPropertyModel.property.constraints && editPropertyModel.property.constraints[0].validValues">
    +
    {{editPropertyModel.property.addOn}} + + + + + + - -
    - - - -
    - -
    - - - - - - - diff --git a/catalog-ui/src/app/view-models/forms/resource-instance-name-form/resource-instance-name.less b/catalog-ui/src/app/view-models/forms/resource-instance-name-form/resource-instance-name.less deleted file mode 100644 index 57698bef17..0000000000 --- a/catalog-ui/src/app/view-models/forms/resource-instance-name-form/resource-instance-name.less +++ /dev/null @@ -1,29 +0,0 @@ -.w-sdc-modal-resource-instance-name { - - .w-sdc-modal-body { - overflow: visible; - } - - .w-sdc-modal-action { - display: flex; - align-items: center; - justify-content: center; - } - - .w-sdc-modal-resource-instance-input { - .p_1; - border: solid 1px @color_p; - height: 45px; - padding: 0 20px; - margin: 0 auto 0 auto; - display: block; - } - .w-sdc-modal-body { - border-bottom: none; - } - - .w-sdc-form .i-sdc-form-item.error::after { - top: 13px; - } - -} diff --git a/catalog-ui/src/app/view-models/modals/confirmation-modal/confirmation-modal-view-model.ts b/catalog-ui/src/app/view-models/modals/confirmation-modal/confirmation-modal-view-model.ts deleted file mode 100644 index 7998d10623..0000000000 --- a/catalog-ui/src/app/view-models/modals/confirmation-modal/confirmation-modal-view-model.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {ValidationUtils, ModalType} from "app/utils"; - -export interface IConfirmationModalModel { - title:string; - message:string; - showComment:boolean; - type:ModalType; -} - -interface IConfirmationModalViewModelScope { - modalInstanceConfirmation:ng.ui.bootstrap.IModalServiceInstance; - confirmationModalModel:IConfirmationModalModel; - comment:any; - commentValidationPattern:RegExp; - editForm:ng.IFormController; - okButtonColor:string; - hideCancelButton:boolean; - ok():any; - cancel():void; -} - -export class ConfirmationModalViewModel { - - static '$inject' = ['$scope', '$uibModalInstance', 'confirmationModalModel', 'CommentValidationPattern', 'ValidationUtils']; - - constructor(private $scope:IConfirmationModalViewModelScope, - private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance, - confirmationModalModel:IConfirmationModalModel, - private CommentValidationPattern:RegExp, - private ValidationUtils:ValidationUtils) { - - this.initScope(confirmationModalModel); - } - - private initScope = (confirmationModalModel:IConfirmationModalModel):void => { - let self = this; - this.$scope.hideCancelButton = false; - this.$scope.modalInstanceConfirmation = this.$uibModalInstance; - this.$scope.confirmationModalModel = confirmationModalModel; - this.$scope.comment = {"text": ''}; - this.$scope.commentValidationPattern = this.CommentValidationPattern; - - this.$scope.ok = ():any => { - self.$uibModalInstance.close(this.ValidationUtils.stripAndSanitize(self.$scope.comment.text)); - }; - - this.$scope.cancel = ():void => { - console.info('Cancel pressed on: ' + this.$scope.confirmationModalModel.title); - self.$uibModalInstance.dismiss(); - }; - - // Set the OK button color according to modal type (standard, error, alert) - let _okButtonColor = 'blue'; // Default - switch (confirmationModalModel.type) { - case ModalType.STANDARD: - _okButtonColor = 'blue'; - break; - case ModalType.ERROR: - _okButtonColor = 'red'; - break; - case ModalType.ALERT: - this.$scope.hideCancelButton = true; - _okButtonColor = 'grey'; - break; - default: - _okButtonColor = 'blue'; - break; - } - this.$scope.okButtonColor = _okButtonColor; - - } -} diff --git a/catalog-ui/src/app/view-models/modals/confirmation-modal/confirmation-modal-view.html b/catalog-ui/src/app/view-models/modals/confirmation-modal/confirmation-modal-view.html deleted file mode 100644 index cb9b159e51..0000000000 --- a/catalog-ui/src/app/view-models/modals/confirmation-modal/confirmation-modal-view.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -
    - - -
    - - -
    - - -
    -
    -
    - -
    diff --git a/catalog-ui/src/app/view-models/modals/confirmation-modal/confirmation-modal.less b/catalog-ui/src/app/view-models/modals/confirmation-modal/confirmation-modal.less deleted file mode 100644 index 666c41d5ed..0000000000 --- a/catalog-ui/src/app/view-models/modals/confirmation-modal/confirmation-modal.less +++ /dev/null @@ -1,30 +0,0 @@ -.w-sdc-modal-confirmation { - form.w-sdc-form{ - padding: 0; - } - - .w-sdc-modal-body-content { - .b_6; - word-break: break-word; - - } - .w-sdc-modal-body { - height: auto; - /* padding: 47px 60px 20px 60px; */ - border-bottom: none; - } - .w-sdc-modal-body-content { - padding: 0; - } - .w-sdc-modal-body-comment { - width: 430px; - height: 127px; - border: solid 1px @color_e; - margin: 20px 0 0 0; - padding: 15px; - } - .w-sdc-modal-label { - .m_14_r; - text-align: left; - } -} diff --git a/catalog-ui/src/app/view-models/modals/conformance-level-modal/conformance-level-modal-view-model.ts b/catalog-ui/src/app/view-models/modals/conformance-level-modal/conformance-level-modal-view-model.ts deleted file mode 100644 index 45696568b4..0000000000 --- a/catalog-ui/src/app/view-models/modals/conformance-level-modal/conformance-level-modal-view-model.ts +++ /dev/null @@ -1,49 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; - -export interface IConformanceLevelModalModelScope { - footerButtons:Array; - modalInstance:ng.ui.bootstrap.IModalServiceInstance; -} - -export class ConformanceLevelModalViewModel { - - static '$inject' = ['$scope', '$uibModalInstance']; - - constructor(private $scope:IConformanceLevelModalModelScope, - private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance) { - - this.initScope(); - } - - private initScope = ():void => { - - this.$scope.modalInstance = this.$uibModalInstance; - - this.$scope.footerButtons = [ - {'name': 'Continue', 'css': 'grey', 'callback': this.$uibModalInstance.close}, - {'name': 'Reject', 'css': 'blue', 'callback': this.$uibModalInstance.dismiss} - ]; - - }; - -} diff --git a/catalog-ui/src/app/view-models/modals/conformance-level-modal/conformance-level-modal-view.html b/catalog-ui/src/app/view-models/modals/conformance-level-modal/conformance-level-modal-view.html deleted file mode 100644 index 5ba0425ea2..0000000000 --- a/catalog-ui/src/app/view-models/modals/conformance-level-modal/conformance-level-modal-view.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - -
    -

    - You are about to distribute a service with models and artifacts created with an older version of the platform. - For such service, new properties, metadata and requirements needed by ECOMP components will not be available. -

    - It is highly recommended that you upgrade the service models and artifacts. -

    - Click "Continue" if you need to distribute the current service version.
    - Click "Reject" if you need to stop the distribution and manually upgrade the service. -

    -
    -
    - -
    diff --git a/catalog-ui/src/app/view-models/modals/conformance-level-modal/conformance-level-modal.less b/catalog-ui/src/app/view-models/modals/conformance-level-modal/conformance-level-modal.less deleted file mode 100644 index 7f195ade83..0000000000 --- a/catalog-ui/src/app/view-models/modals/conformance-level-modal/conformance-level-modal.less +++ /dev/null @@ -1,3 +0,0 @@ -.conformance-level-modal{ - -} diff --git a/catalog-ui/src/app/view-models/modals/email-modal/email-modal-view-model.ts b/catalog-ui/src/app/view-models/modals/email-modal/email-modal-view-model.ts deleted file mode 100644 index 095d1438b2..0000000000 --- a/catalog-ui/src/app/view-models/modals/email-modal/email-modal-view-model.ts +++ /dev/null @@ -1,116 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {IAppConfigurtaion, Component, AsdcComment} from "app/models"; -import {ValidationUtils} from "app/utils"; - -export interface IEmailModalModel_Email { - to:string; - subject:string; - message:string; -} - -export interface IEmailModalModel_Data { - component:Component; - stateUrl:string; -} - -export interface IEmailModalModel { - title:string; - email:IEmailModalModel_Email; - data:IEmailModalModel_Data; -} - -interface IEmailModalViewModelScope { - modalInstanceEmail:ng.ui.bootstrap.IModalServiceInstance; - emailModalModel:IEmailModalModel; - submitInProgress:boolean; - commentValidationPattern:RegExp; - isLoading:boolean; - submit():any; - cancel():void; - validateField(field:any):boolean; -} - -export class EmailModalViewModel { - - static '$inject' = ['$scope', '$filter', 'sdcConfig', '$uibModalInstance', 'emailModalModel', 'ValidationUtils', 'CommentValidationPattern']; - - constructor(private $scope:IEmailModalViewModelScope, - private $filter:ng.IFilterService, - private sdcConfig:IAppConfigurtaion, - private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance, - private emailModalModel:IEmailModalModel, - private ValidationUtils:ValidationUtils, - private CommentValidationPattern:RegExp) { - - this.initScope(emailModalModel); - } - - private initScope = (emailModalModel:IEmailModalModel):void => { - this.$scope.emailModalModel = emailModalModel; - this.$scope.submitInProgress = false; - this.$scope.commentValidationPattern = this.CommentValidationPattern; - this.$scope.modalInstanceEmail = this.$uibModalInstance; - - this.$scope.submit = ():any => { - - let onSuccess = (component:Component) => { - this.$scope.isLoading = false; - this.$scope.submitInProgress = false; - // showing the outlook modal according to the config json - if (this.sdcConfig.showOutlook) { - let link:string = encodeURI(this.sdcConfig.api.baseUrl + "?folder=Ready_For_Testing"); - let outlook:string = this.$filter('translate')("EMAIL_OUTLOOK_MESSAGE", "{'to': '" + emailModalModel.email.to + "','subject': '" + emailModalModel.email.subject + "','message': '" + emailModalModel.email.message + "', 'entityNameAndVersion': '" + emailModalModel.email.subject + "','link': '" + link + "'}"); - window.location.href = outlook; // Open outlook with the email to send - } - this.$uibModalInstance.close(component); // Close the dialog - }; - - let onError = () => { - this.$scope.isLoading = false; - this.$scope.submitInProgress = false; - this.$uibModalInstance.close(); // Close the dialog - }; - - // Submit to server - // Prevent from user pressing multiple times on submit. - if (this.$scope.submitInProgress === false) { - this.$scope.isLoading = true; - this.$scope.submitInProgress = true; - let comment:AsdcComment = new AsdcComment(); - comment.userRemarks = emailModalModel.email.message; - emailModalModel.data.component.changeLifecycleState(emailModalModel.data.stateUrl, comment).then(onSuccess, onError); - } - }; - - this.$scope.cancel = ():void => { - this.$uibModalInstance.dismiss(); - }; - - this.$scope.validateField = (field:any):boolean => { - if (field && field.$dirty && field.$invalid) { - return true; - } - return false; - }; - } -} diff --git a/catalog-ui/src/app/view-models/modals/email-modal/email-modal-view.html b/catalog-ui/src/app/view-models/modals/email-modal/email-modal-view.html deleted file mode 100644 index 612fe226aa..0000000000 --- a/catalog-ui/src/app/view-models/modals/email-modal/email-modal-view.html +++ /dev/null @@ -1,93 +0,0 @@ - - - diff --git a/catalog-ui/src/app/view-models/modals/email-modal/email-modal.less b/catalog-ui/src/app/view-models/modals/email-modal/email-modal.less deleted file mode 100644 index 471089fa1a..0000000000 --- a/catalog-ui/src/app/view-models/modals/email-modal/email-modal.less +++ /dev/null @@ -1,57 +0,0 @@ -.w-sdc-modal-email { - - .w-sdc-modal-body { - border-bottom: none; - } - - form.w-sdc-form{ - padding: 0; - - .i-sdc-form-item { - clear: both; - label { - min-height: 30px; - padding-top: 4px; - } - - .col-sm-10 { - padding-right: 0; - } - - } - - .w-sdc-modal-body-email { - border-style: solid; - border-width: 1px; - border-color: @color_e; - box-sizing: border-box; - width: 100%; - height: 127px; - margin-bottom: 20px; - } - - label {.m_14_m; text-align: left;} - input {.m_14_r;} - textarea {.m_14_r;} - /* I made the subject and to fields as input (for future use), but for now they look like labels: */ - input:disabled { - .bg_c; - border: none; - } - } - - .w-sdc-modal-action { - background-color: @main_color_p; - padding: 0 13px 0 0; - height: 90px; - line-height: 65px; - - button {width: 174px;} - } - - .w-sdc-form .i-sdc-form-item label.required::before { - position: absolute; - left: -13px; - } - -} diff --git a/catalog-ui/src/app/view-models/modals/error-modal/error-403-view.html b/catalog-ui/src/app/view-models/modals/error-modal/error-403-view.html index ba08b51fa3..1cab8adb3b 100644 --- a/catalog-ui/src/app/view-models/modals/error-modal/error-403-view.html +++ b/catalog-ui/src/app/view-models/modals/error-modal/error-403-view.html @@ -13,7 +13,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -
    diff --git a/catalog-ui/src/app/view-models/modals/icons-modal/icons-modal-view.html b/catalog-ui/src/app/view-models/modals/icons-modal/icons-modal-view.html index 75bc82dcfd..86c776a7ee 100644 --- a/catalog-ui/src/app/view-models/modals/icons-modal/icons-modal-view.html +++ b/catalog-ui/src/app/view-models/modals/icons-modal/icons-modal-view.html @@ -13,7 +13,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -
    diff --git a/catalog-ui/src/app/view-models/modals/message-modal/message-base-modal-model.ts b/catalog-ui/src/app/view-models/modals/message-modal/message-base-modal-model.ts deleted file mode 100644 index b987f1088e..0000000000 --- a/catalog-ui/src/app/view-models/modals/message-modal/message-base-modal-model.ts +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {SEVERITY} from "app/utils"; - -export interface IMessageModalModel { - title:string; - message:string; - severity:SEVERITY; -} - -export interface IMessageModalViewModelScope extends ng.IScope { - footerButtons:Array; - messageModalModel:IMessageModalModel; - modalInstanceError:ng.ui.bootstrap.IModalServiceInstance; - ok():void; -} - -export class MessageModalViewModel { - - constructor(private $baseScope:IMessageModalViewModelScope, - private $baseModalInstance:ng.ui.bootstrap.IModalServiceInstance, - private baseMessageModalModel:IMessageModalModel) { - - this.initScope(baseMessageModalModel); - } - - private initScope = (messageModalViewModel:IMessageModalModel):void => { - - this.$baseScope.messageModalModel = messageModalViewModel; - this.$baseScope.modalInstanceError = this.$baseModalInstance; - - this.$baseScope.ok = ():void => { - this.$baseModalInstance.close(); - }; - - this.$baseScope.footerButtons = [ - { - 'name': 'OK', - 'css': 'grey', - 'callback': this.$baseScope.ok - } - ]; - } -} diff --git a/catalog-ui/src/app/view-models/modals/message-modal/message-client-modal/client-message-modal-view-model.ts b/catalog-ui/src/app/view-models/modals/message-modal/message-client-modal/client-message-modal-view-model.ts deleted file mode 100644 index f2b2217645..0000000000 --- a/catalog-ui/src/app/view-models/modals/message-modal/message-client-modal/client-message-modal-view-model.ts +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {IMessageModalModel, MessageModalViewModel, IMessageModalViewModelScope} from "../message-base-modal-model"; - -export interface IClientMessageModalModel extends IMessageModalModel { -} - -export interface IClientMessageModalViewModelScope extends IMessageModalViewModelScope { - clientMessageModalModel:IClientMessageModalModel; -} - -export class ClientMessageModalViewModel extends MessageModalViewModel { - - static '$inject' = ['$scope', '$uibModalInstance', 'clientMessageModalModel']; - - constructor(private $scope:IClientMessageModalViewModelScope, - private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance, - private clientMessageModalModel:IClientMessageModalModel) { - - super($scope, $uibModalInstance, clientMessageModalModel); - } - -} diff --git a/catalog-ui/src/app/view-models/modals/message-modal/message-client-modal/client-message-modal-view.html b/catalog-ui/src/app/view-models/modals/message-modal/message-client-modal/client-message-modal-view.html deleted file mode 100644 index f0a4f9a8db..0000000000 --- a/catalog-ui/src/app/view-models/modals/message-modal/message-client-modal/client-message-modal-view.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - -
    -
    -
    -
    - -
    - -
    diff --git a/catalog-ui/src/app/view-models/modals/message-modal/message-client-modal/client-message-modal.less b/catalog-ui/src/app/view-models/modals/message-modal/message-client-modal/client-message-modal.less deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal-view-model.ts b/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal-view-model.ts deleted file mode 100644 index b92069fce2..0000000000 --- a/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal-view-model.ts +++ /dev/null @@ -1,46 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {IMessageModalModel, IMessageModalViewModelScope, MessageModalViewModel} from "../message-base-modal-model"; - -export interface IServerMessageModalModel extends IMessageModalModel { - status:string; - messageId:string; - - -} - -export interface IServerMessageModalViewModelScope extends IMessageModalViewModelScope { - serverMessageModalModel:IServerMessageModalModel; -} - -export class ServerMessageModalViewModel extends MessageModalViewModel { - - static '$inject' = ['$scope', '$uibModalInstance', 'serverMessageModalModel']; - - constructor(private $scope:IServerMessageModalViewModelScope, - private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance, - private serverMessageModalModel:IServerMessageModalModel) { - - super($scope, $uibModalInstance, serverMessageModalModel); - } - -} diff --git a/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal-view.html b/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal-view.html deleted file mode 100644 index 7d3204c095..0000000000 --- a/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal-view.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -
    -
    -
    Error code: {{messageModalModel.messageId}}
    -
    Status code: {{messageModalModel.status}}
    -
    -
    -
    - -
    diff --git a/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal.less b/catalog-ui/src/app/view-models/modals/message-modal/message-server-modal/server-message-modal.less deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal-view-model.ts b/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal-view-model.ts deleted file mode 100644 index 01394a3c33..0000000000 --- a/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal-view-model.ts +++ /dev/null @@ -1,272 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {ComponentType, SEVERITY, FileUtils, ModalsHandler, ComponentFactory} from "app/utils"; -import {OnboardingService, CacheService} from "app/services"; -import {Component, IComponent, IUser, IAppConfigurtaion, Resource} from "app/models"; -import {IServerMessageModalModel} from "../message-modal/message-server-modal/server-message-modal-view-model"; -import {Dictionary} from "app/utils"; -import * as _ from 'underscore'; - -interface IOnboardingModalViewModelScope { - modalOnboarding:ng.ui.bootstrap.IModalServiceInstance; - componentsList:Array; - tableHeadersList:Array; - selectedComponent:Component; - componentFromServer:Component; - reverse:boolean; - sortBy:string; - searchBind:string; - okButtonText:string; - isCsarComponentExists:boolean; - user:IUser; - isLoading:boolean; - - //this is for UI paging - numberOfItemsToDisplay:number; - allItemsDisplayed:boolean; - - doSelectComponent(component:Component):void; - doUpdateCsar():void; - doImportCsar():void; - sort(sortBy:string):void; - downloadCsar(packageId:string):void; - increaseNumItemsToDisplay():void; -} - -export class OnboardingModalViewModel { - - static '$inject' = [ - '$scope', - '$filter', - '$state', - 'sdcConfig', - '$uibModalInstance', - 'Sdc.Services.OnboardingService', - 'okButtonText', - 'currentCsarUUID', - 'currentCsarVersion', - 'Sdc.Services.CacheService', - 'FileUtils', - 'ComponentFactory', - 'ModalsHandler' - ]; - - constructor(private $scope:IOnboardingModalViewModelScope, - private $filter:ng.IFilterService, - private $state:any, - private sdcConfig:IAppConfigurtaion, - private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance, - private onBoardingService:OnboardingService, - private okButtonText:string, - private currentCsarUUID:string, - private currentCsarVersion:string, - private cacheService:CacheService, - private fileUtils:FileUtils, - private componentFactory:ComponentFactory, - private modalsHandler:ModalsHandler) { - - this.init(); - } - - /** - * Called from controller constructor, this will call onboarding service to get list - * of "mini" components (empty components created from CSAR). - * The list is inserted to componentsList on $scope. - * And then call initScope method. - */ - private init = ():void => { - this.initOnboardingComponentsList(); - }; - - private initScope = ():void => { - - this.initSortedTableScope(); - this.initModalScope(); - this.$scope.sortBy = "name"; // Default sort by - this.$scope.user = this.cacheService.get('user'); - this.$scope.okButtonText = this.okButtonText; - this.$scope.numberOfItemsToDisplay = 0; - this.$scope.allItemsDisplayed = false; - - // Dismiss the modal and pass the "mini" component to workspace general page - this.$scope.doImportCsar = ():void => { - - this.$uibModalInstance.close({ - componentCsar: this.$scope.selectedComponent, - type: ComponentType.RESOURCE.toLowerCase() - }); - }; - - this.$scope.doUpdateCsar = ():void => { - - // Change the component version to the CSAR version we want to update. - if(!this.currentCsarVersion || this.currentCsarVersion != (this.$scope.selectedComponent).csarVersion) { - this.$uibModalInstance.close({ - componentCsar: this.$scope.selectedComponent, - previousComponent: this.$scope.componentFromServer, - type: this.$scope.componentFromServer.componentType.toLowerCase() - - }); - - } else { - this.$uibModalInstance.close(); - } - }; - - this.$scope.downloadCsar = (packageId:string):void => { - this.$scope.isLoading = true; - this.onBoardingService.downloadOnboardingCsar(packageId).then( - (file:any):void => { - this.$scope.isLoading = false; - if (file) { - this.fileUtils.downloadFile(file, packageId + '.csar'); - } - }, ():void => { - this.$scope.isLoading = false; - var data:IServerMessageModalModel = { - title: 'Download error', - message: "Error downloading file", - severity: SEVERITY.ERROR, - messageId: "", - status: "" - }; - this.modalsHandler.openServerMessageModal(data); - } - ); - }; - - this.$scope.increaseNumItemsToDisplay = ():void => { - this.$scope.numberOfItemsToDisplay = this.$scope.numberOfItemsToDisplay + 40; - if (this.$scope.componentsList) { - this.$scope.allItemsDisplayed = this.$scope.numberOfItemsToDisplay >= this.$scope.componentsList.length; - } - }; - - // When the user select a row, set the component as selectedComponent - this.$scope.doSelectComponent = (component:Component):void => { - - if (this.$scope.selectedComponent === component) { - // Collapse the item - this.$scope.selectedComponent = undefined; - return; - } - - this.$scope.isLoading = true; - this.$scope.componentFromServer = undefined; - this.$scope.selectedComponent = component; - - let onSuccess = (componentFromServer:Component):void => { - this.$scope.isLoading = false; - if (componentFromServer) { - this.$scope.componentFromServer = componentFromServer; - this.$scope.isCsarComponentExists = true; - } else { - this.$scope.componentFromServer = component; - this.$scope.isCsarComponentExists = false; - } - }; - - let onError = ():void => { - this.$scope.isLoading = false; - this.$scope.componentFromServer = component; - this.$scope.isCsarComponentExists = false; - }; - - this.onBoardingService.getComponentFromCsarUuid((component).csarUUID).then(onSuccess, onError); - }; - - }; - - private initSortedTableScope = ():void => { - this.$scope.tableHeadersList = [ - {title: 'Name', property: 'name'}, - {title: 'Vendor', property: 'vendorName'}, - {title: 'Category', property: 'categories'}, - {title: 'Version', property: 'csarVersion'}, - {title: 'Type', property: 'resourceType'}, - {title: '#', property: 'importAndUpdate'} - //{title: 'Date', property: 'componentDate'} - ]; - - this.$scope.sort = (sortBy:string):void => { - this.$scope.reverse = (this.$scope.sortBy === sortBy) ? !this.$scope.reverse : false; - this.$scope.sortBy = sortBy; - }; - }; - - private initModalScope = ():void => { - // Enable the modal directive to close - this.$scope.modalOnboarding = this.$uibModalInstance; - }; - - private initOnboardingComponentsList = ():void => { - let onSuccess = (onboardingResponse:Array):void => { - initMaxVersionOfItemsInList(onboardingResponse); - - if (this.currentCsarUUID) { - //this.$scope.componentsList = this.$filter('filter')(this.$scope.componentsList, {csarUUID: this.currentCsarUUID}); - this.$scope.componentsList = this.$filter('filter')(this.$scope.componentsList, - (input):boolean => { - return input.csarUUID === this.currentCsarUUID; - } - ); - } - this.initScope(); - }; - - let onError = ():void => { - console.log("Error getting onboarding list"); - this.initScope(); - }; - - let initMaxVersionOfItemsInList = (onboardingResponse:Array):void => { - // Get only the latest version of each item - this.$scope.componentsList = []; - - // Get all unique items from the list - let uniqueItems:Array = _.uniq(onboardingResponse, false, (item:any):void=>{ - return item.packageId; - }); - - // Loop on all the items with unique packageId - _.each(uniqueItems, (item:any):void=> { - // Find all the items that has same packageId - let ItemsFound:Array = _.filter(onboardingResponse, (inListItem:any):any => { - return inListItem.packageId === item.packageId; - }); - - // Loop on all the items with same packageId and find the max version. - let maxItem:any; - _.each(ItemsFound, (ItemFound:any):void=> { - if (!maxItem) { - maxItem = ItemFound; - } else if (maxItem && parseInt(maxItem.csarVersion) < parseInt(ItemFound.csarVersion)) { - maxItem = ItemFound; - } - }); - this.$scope.componentsList.push(maxItem); - }); - }; - - this.onBoardingService.getOnboardingComponents().then(onSuccess, onError); - }; -} diff --git a/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal-view.html b/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal-view.html deleted file mode 100644 index 7f19389bdf..0000000000 --- a/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal-view.html +++ /dev/null @@ -1,165 +0,0 @@ - - - - -
    -
    -

    Select one of the software product component below:

    -
    - - -
    - -
    -
    - - -
    -
    {{header.title}} - -
    -
    - - -
    - - - -
    - There are no software product component to display -
    - -
    - - -
    - - -
    - - {{component.name}} -
    - - -
    - {{component.vendorName}} -
    - - -
    - {{component.categories[0].name}} {{component.categories[0].subcategories[0].name}} -
    - - -
    - {{component.csarVersion}} -
    - - -
    - {{component.resourceType}} -
    - - -
    - -
    - -
    - -
    -
    VSP Description:
    - {{component.description}} -
    - -
    -
    - -
    Name: {{componentFromServer.name}}
    -
    Lifecycle: {{componentFromServer.lifecycleState}}
    -
    Creator: {{componentFromServer.creatorFullName}}
    -
    -
    - -
    -
    - -
    UUID: {{componentFromServer.uuid}}
    -
    Version: {{componentFromServer.version}}
    -
    Modifier: {{componentFromServer.lastUpdaterFullName}}
    -
    - Designers cannot update a VSP if the VF is checked out by another user. -
    -
    - Designers cannot update a VSP if the VF is in Ready for testing state. -
    -
    -
    - -
    - -
    - -
    - - - - - -
    - -
    -
    - -
    -
    -
    -
    - - -
    diff --git a/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal.less b/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal.less deleted file mode 100644 index ccf4fb00b5..0000000000 --- a/catalog-ui/src/app/view-models/modals/onboarding-modal/onboarding-modal.less +++ /dev/null @@ -1,149 +0,0 @@ -.w-sdc-modal-onboarding { - - width: 100%; - display: inline-block; - - .general-info-button{ - position: relative; - top: -40px; - left: 95px; - float: left; - } - - .title-wrapper { - display: flex; - justify-content: space-between; - align-items: flex-end; - - .sub-title { - .m_14_r; - float:left; - } - } - - .w-sdc-classic-btn { - float: right; - margin-bottom: 10px; - } - - .table{ - height: 472px; - margin-bottom: 0; - } - - .table-container-flex { - margin-top: 10px; - - .table { - .body { - .data-row + div.item-opened { - word-wrap: break-word; - display: flex; - justify-content: space-between; - padding: 10px 0; - - .item-opened-description-title, - .item-opened-metadata-title { - .m_14_m; - } - - .item-opened-description, - .item-opened-metadata1, - .item-opened-metadata2, - .item-opened-metadata3 { - .th { .m_14_m; } - flex-basis: 0; - overflow: hidden; - padding: 5px 15px; - } - - .item-opened-description, - .item-opened-metadata3 { - border-right: 1px solid @main_color_o; - } - - .item-opened-metadata2 { - word-break: break-word; - .note { - color: @func_color_q; - } - } - - .item-opened-icon { - flex-basis: 0; - overflow: hidden; - padding: 5px 15px; - align-self: center; - } - - .item-opened-description {flex-grow: 25.3;} - .item-opened-metadata1 {flex-grow: 25;} - .item-opened-metadata2 {flex-grow: 45;} - .item-opened-metadata3 { - flex-grow: 10; - .info-button{ - float: right; - } - } - .item-opened-icon {flex-grow: 10.1;} - } - } - } - - .flex-item:nth-child(1) { - flex-grow: 25; - .hand; - span.table-arrow { - margin-right: 7px; - } - } - - .flex-item:nth-child(2) {flex-grow: 25;} - .flex-item:nth-child(3) {flex-grow: 30;} - .flex-item:nth-child(4) {flex-grow: 10; text-align: center; } - .flex-item:nth-child(5) {flex-grow: 10; text-align: center; } - .flex-item:nth-child(6) {flex-grow: 10; } - - } - - .download-file-btn { - cursor: pointer; - margin-left: 4px; - } - - .refresh-file-btn, - .import-file-btn { - cursor: pointer; - margin-left: 20px; - } - - .top-search { - float: right; - position: relative; - - input.search-text { - .border-radius(2px); - width: 245px; - height: 32px; - line-height: 32px; - border: 1px solid @main_color_o; - margin: 0; - outline: none; - text-indent: 10px; - - &::-webkit-input-placeholder { font-style: italic; } /* Safari, Chrome and Opera */ - &:-moz-placeholder { font-style: italic; } /* Firefox 18- */ - &::-moz-placeholder { font-style: italic; } /* Firefox 19+ */ - &:-ms-input-placeholder { font-style: italic; } /* IE 10+ */ - &:-ms-input-placeholder { font-style: italic; } /* Edge */ - } - - .magnification { - position: absolute; - top: 10px; - right: 10px; - } - - } - -} diff --git a/catalog-ui/src/app/view-models/onboard-vendor/onboard-vendor-view-model.ts b/catalog-ui/src/app/view-models/onboard-vendor/onboard-vendor-view-model.ts index 10f41f6b61..fc3672cc50 100644 --- a/catalog-ui/src/app/view-models/onboard-vendor/onboard-vendor-view-model.ts +++ b/catalog-ui/src/app/view-models/onboard-vendor/onboard-vendor-view-model.ts @@ -22,7 +22,7 @@ import * as _ from "underscore"; import {IUserProperties} from "app/models"; import {MenuItemGroup, MenuItem} from "app/utils"; -import {CacheService} from "app/services"; +import {CacheService} from "app/services-ng2"; declare var PunchOutRegistry; export class BreadcrumbsMenuItem { diff --git a/catalog-ui/src/app/view-models/onboard-vendor/onboard-vendor-view.html b/catalog-ui/src/app/view-models/onboard-vendor/onboard-vendor-view.html index fc1140ebf0..2d8010bd37 100644 --- a/catalog-ui/src/app/view-models/onboard-vendor/onboard-vendor-view.html +++ b/catalog-ui/src/app/view-models/onboard-vendor/onboard-vendor-view.html @@ -13,7 +13,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -
    diff --git a/catalog-ui/src/app/view-models/onboard-vendor/onboard-vendor.less b/catalog-ui/src/app/view-models/onboard-vendor/onboard-vendor.less index 71a3101412..1e091e957d 100644 --- a/catalog-ui/src/app/view-models/onboard-vendor/onboard-vendor.less +++ b/catalog-ui/src/app/view-models/onboard-vendor/onboard-vendor.less @@ -76,22 +76,6 @@ } } - &.READY_FOR_CERTIFICATION { - .i-sdc-categories-list-item-icon { - background: url('/assets/styles/images/sprites/sprite-global-old.png') no-repeat -53px -2985px; - width: 14px; - height: 16px; - } - } - - &.CERTIFICATION_IN_PROGRESS { - .i-sdc-categories-list-item-icon { - background: url('/assets/styles/images/sprites/sprite-global-old.png') no-repeat -53px -2934px; - width: 14px; - height: 16px; - } - } - &.DISTRIBUTED, &.TBD { .i-sdc-categories-list-item-icon { diff --git a/catalog-ui/src/app/view-models/plugins/plugins-tab-view-model.ts b/catalog-ui/src/app/view-models/plugins/plugins-tab-view-model.ts deleted file mode 100644 index d25cd19bff..0000000000 --- a/catalog-ui/src/app/view-models/plugins/plugins-tab-view-model.ts +++ /dev/null @@ -1,83 +0,0 @@ -/* - -* Copyright (c) 2018 AT&T Intellectual Property. - -* - -* 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. - -*/ - -import {IUserProperties, Plugin} from "app/models"; -import {CacheService} from "app/services"; -import {PluginsService} from "../../ng2/services/plugins.service"; - - -interface IPluginsTabViewModelScope extends ng.IScope { - plugin: Plugin - user: IUserProperties; - version: string; - queryParams: Object; - isLoading: boolean; - - onLoadingDone(plugin: Plugin): void; -} - -export class PluginsTabViewModel { - static '$inject' = [ - '$scope', - '$stateParams', - 'Sdc.Services.CacheService', - 'PluginsService' - ]; - - constructor(private $scope: IPluginsTabViewModelScope, - private $stateParams: any, - private cacheService: CacheService, - private pluginsService: PluginsService) { - - this.initScope(); - } - - private initScope = (): void => { - this.$scope.plugin = this.pluginsService.getPluginByStateUrl(this.$stateParams.path); - this.$scope.version = this.cacheService.get('version'); - this.$scope.user = this.cacheService.get('user'); - - this.$scope.isLoading = true; - - this.$scope.queryParams = { - userId: this.$scope.user.userId, - userRole: this.$scope.user.role, - displayType: "tab", - parentUrl: window.location.origin, - eventsClientId: this.$scope.plugin.pluginId - }; - - this.$scope.onLoadingDone = (plugin: Plugin) => { - if (plugin.pluginId == this.$scope.plugin.pluginId) { - this.$scope.isLoading = false; - } - }; - } -} diff --git a/catalog-ui/src/app/view-models/plugins/plugins-tab-view.html b/catalog-ui/src/app/view-models/plugins/plugins-tab-view.html deleted file mode 100644 index 50c5766625..0000000000 --- a/catalog-ui/src/app/view-models/plugins/plugins-tab-view.html +++ /dev/null @@ -1,21 +0,0 @@ - - -
    - - - -
    diff --git a/catalog-ui/src/app/view-models/plugins/plugins-tab.less b/catalog-ui/src/app/view-models/plugins/plugins-tab.less deleted file mode 100644 index 3cb5d1b421..0000000000 --- a/catalog-ui/src/app/view-models/plugins/plugins-tab.less +++ /dev/null @@ -1,2 +0,0 @@ -.plugins-tab-container { -} diff --git a/catalog-ui/src/app/view-models/preloading/preloading-view.html b/catalog-ui/src/app/view-models/preloading/preloading-view.html deleted file mode 100644 index e894587fdc..0000000000 --- a/catalog-ui/src/app/view-models/preloading/preloading-view.html +++ /dev/null @@ -1,25 +0,0 @@ - - -
    -

    -

    - -
    -
    Loading...
    -
    - -
    diff --git a/catalog-ui/src/app/view-models/preloading/preloading-view.ts b/catalog-ui/src/app/view-models/preloading/preloading-view.ts deleted file mode 100644 index d629d298f2..0000000000 --- a/catalog-ui/src/app/view-models/preloading/preloading-view.ts +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; - -interface IPreLoadingViewScope { - startZoomIn:boolean; -} - -export class PreLoadingViewModel { - - static '$inject' = ['$scope']; - - constructor(private $scope:IPreLoadingViewScope) { - this.init($scope); - } - - private init = ($scope:IPreLoadingViewScope):void => { - this.animate($('.caption1'), 'fadeInUp', 400); - this.animate($('.caption2'), 'fadeInUp', 800); - }; - - private animate = (element:any, animation:string, when:number):void => { - window.setTimeout(()=> { - element.addClass("animated " + animation); - element[0].style = "visibility: visible;"; - }, when); - }; - -} diff --git a/catalog-ui/src/app/view-models/shared/notification-custom-template.html b/catalog-ui/src/app/view-models/shared/notification-custom-template.html index 869c49bacf..9456b87093 100644 --- a/catalog-ui/src/app/view-models/shared/notification-custom-template.html +++ b/catalog-ui/src/app/view-models/shared/notification-custom-template.html @@ -13,7 +13,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -
    diff --git a/catalog-ui/src/app/view-models/shared/notification-template.less b/catalog-ui/src/app/view-models/shared/notification-template.less new file mode 100644 index 0000000000..5baf10d411 --- /dev/null +++ b/catalog-ui/src/app/view-models/shared/notification-template.less @@ -0,0 +1,53 @@ +.notification-container{ + display: flex; + padding: 15px 11px; + float: left; + .icon-container{ + flex-grow: 1; + margin-right: 20px; + .icon-circle{ + background-color: black; + height: 40px; + width: 40px; + border-radius: 50%; + display: flex; + align-items: center; + margin-right: 0; + background-color: rgba(255, 255, 255, 0.3); + .icon{ + margin: 0 auto; + display: block; + } + } + } + .msg-content{ + flex-grow: 3; + h3{ + border-bottom: none; + font-weight: 400; + .f-type._18_m; + } + .message{ + font-weight: 300; + .f-type._14_m; + } + } +} +.ui-notification.success{ + background-color: @main_color_d; + .icon{ + .notification-success-icon; + } +} +.ui-notification.error{ + background-color: @func_color_q; + .icon{ + .notification-error-icon; + } +} +.ui-notification.info{ + background-color: @main_color_a; + .icon{ + .notification-process-icon; + } +} diff --git a/catalog-ui/src/app/view-models/support/support-view-model.ts b/catalog-ui/src/app/view-models/support/support-view-model.ts deleted file mode 100644 index 5703a74e97..0000000000 --- a/catalog-ui/src/app/view-models/support/support-view-model.ts +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {CacheService} from "app/services"; - -interface ISupportViewModelScope { - version:string; -} - -export class SupportViewModel { - - static '$inject' = ['$scope', 'Sdc.Services.CacheService']; - - constructor(private $scope:ISupportViewModelScope, - private cacheService:CacheService) { - this.$scope.version = this.cacheService.get('version'); - } -} diff --git a/catalog-ui/src/app/view-models/support/support-view.html b/catalog-ui/src/app/view-models/support/support-view.html deleted file mode 100644 index e85373b79d..0000000000 --- a/catalog-ui/src/app/view-models/support/support-view.html +++ /dev/null @@ -1,47 +0,0 @@ - - -
    - -
    - -
    Support
    - -
    -
    -
    -
    -
    In Design ({{numOfCheckOutEntities+numOfCheckInEntities}})
    -
    Checked Out ({{numOfCheckOutEntities}})
    -
    Checked In ({{numOfCheckInEntities}})
    -
    -
    -
    Completed Design ({{numOfReadyForCertificationEntities+numOfCertificationInProgressEntities+numOfCertifiedEntities}})
    -
    Ready For Certification ({{numOfReadyForCertificationEntities}})
    -
    Certification In Progress ({{numOfCertificationInProgressEntities}})
    -
    Certified ({{numOfCertifiedEntities}})
    -
    -
    -
    Catalog
    -
    Support
    -
    -
    -
    -
    diff --git a/catalog-ui/src/app/view-models/support/support.less b/catalog-ui/src/app/view-models/support/support.less deleted file mode 100644 index 8159e38320..0000000000 --- a/catalog-ui/src/app/view-models/support/support.less +++ /dev/null @@ -1,8 +0,0 @@ -.w-sdc-left-sidebar-in-progress, -.w-sdc-left-sidebar-following { - .b_7; -} - -.w-sdc-left-sidebar-following { - padding: 13px 0; -} diff --git a/catalog-ui/src/app/view-models/tabs/general-tab.less b/catalog-ui/src/app/view-models/tabs/general-tab.less deleted file mode 100644 index 936b3e3414..0000000000 --- a/catalog-ui/src/app/view-models/tabs/general-tab.less +++ /dev/null @@ -1,122 +0,0 @@ -.sdc-general-tab { - - display: flex; - min-height: 100%; - flex-flow: column; - - .sdc-edit-icon { - .sprite; - .e-sdc-small-icon-pencil; - } - .sdc-general-tab-title { - - .f-color.a; - .f-type._14_m; - padding: 0px 0px 15px 20px; - border-bottom: 1px solid @main_color_o; - } - - .sdc-general-tab-sub-title { - - .f-color.a; - .f-type._14_m; - padding: 15px 20px 15px 20px; - - } - - //scrollbar - .general-tab-scrollbar-container { - - .perfect-scrollbar; - width: 100%; - } - - //plus minus expand collapse - .general-tab-expand-collapse { - - &.expanded { - .expand-collapse-title { - .expand-collapse-title-icon { - .expand-collapse-minus-icon; - } - } - } - - .expand-collapse-title { - - padding: 8px 20px 4px 20px; - cursor: pointer; - &:hover { - background-color: @main_color_o; - } - - .expand-collapse-title-icon { - .hand; - .sprite-new; - .expand-collapse-plus-icon; - } - .expand-collapse-title-text { - max-width: 225px; - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - padding-left: 10px; - line-height: 15px; - } - } - .selected { - background-color: @main_color_a; - .f-color.p; - } - - } - - .expand-collapse-sub-title { - max-width: 190px; - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - padding: 10px 0 0 43px; - - } - - //resizable view - .resizable-container { - - flex: 1 1 auto; - display: flex; - flex-direction: column; - height: 90%; - - .resizable-section { - min-height: 50px; - flex: 1; - display: flex; - flex-flow: column; - &.resizable { - flex: 0 0 300px; - } - } - - //this is the resizable icon custom design for the angular resizable directive - .rg-top { - span { - margin-top: -5px; - &:before { - border-top: 1px dotted @main_color_m; - content: ''; - display: inline-block; - width: 39px; - height: 6px; - } - - border-top: 1px dotted @main_color_m; - border-bottom: 1px dotted @main_color_m; - width: 39px; - height: 4px; - } - } - } -} diff --git a/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy-view-model.ts b/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy-view-model.ts deleted file mode 100644 index f752e3dba7..0000000000 --- a/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy-view-model.ts +++ /dev/null @@ -1,134 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {ModalsHandler} from "app/utils"; -import {PropertyModel, DisplayModule, Component, ComponentInstance, Tab, Module} from "app/models"; -import {ExpandCollapseListData} from "app/directives/utils/expand-collapse-list-header/expand-collapse-list-header"; - -interface IComponentInstancesMap { - [key:string]: ComponentInstance -} - -export interface IHierarchyScope extends ng.IScope { - component:Component; - selectedIndex:number; - selectedModule:DisplayModule; - singleTab:Tab; - isLoading:boolean; - expandCollapseArtifactsList:ExpandCollapseListData; - expandCollapsePropertiesList:ExpandCollapseListData; - selectedInstanceId:string; - componentInstancesMap:IComponentInstancesMap; - - onModuleSelected(module:Module, selectedIndex:number, componentInstanceId?:string):void; - onModuleNameChanged(module:DisplayModule):void; - updateHeatName():void; - loadInstanceModules(instance:ComponentInstance):ng.IPromise; - openEditPropertyModal(property:PropertyModel, filteredProperties:Array):void; -} - -export class HierarchyViewModel { - - static '$inject' = [ - '$scope', - '$q', - 'ModalsHandler' - ]; - - constructor(private $scope:IHierarchyScope, private $q:ng.IQService, private ModalsHandler:ModalsHandler) { - this.$scope.component = this.$scope.singleTab.data; - this.$scope.isLoading = false; - this.$scope.expandCollapseArtifactsList = new ExpandCollapseListData(); - this.$scope.expandCollapsePropertiesList = new ExpandCollapseListData(); - this.$scope.componentInstancesMap = {}; - this.initScopeMethods(); - } - - private initScopeMethods():void { - - let collapseModuleData = ():void => { - this.$scope.expandCollapseArtifactsList.expandCollapse = false; - this.$scope.expandCollapsePropertiesList.expandCollapse = false; - this.$scope.expandCollapseArtifactsList.orderByField = "artifactName"; - this.$scope.expandCollapsePropertiesList.orderByField = "name"; - }; - - this.$scope.onModuleSelected = (module:Module, selectedIndex:number, componentInstanceId?:string):void => { - - let onSuccess = (module:DisplayModule) => { - console.log("Module Loaded: ", module); - this.$scope.selectedModule = module; - this.$scope.isLoading = false; - collapseModuleData(); - }; - - let onFailed = () => { - this.$scope.isLoading = false; - }; - - this.$scope.selectedIndex = selectedIndex; - if (!this.$scope.selectedModule || (this.$scope.selectedModule && this.$scope.selectedModule.uniqueId != module.uniqueId)) { - this.$scope.isLoading = true; - if (this.$scope.component.isService()) { - this.$scope.selectedInstanceId = componentInstanceId; - this.$scope.component.getModuleInstanceForDisplay(componentInstanceId, module.uniqueId).then(onSuccess, onFailed); - } else { - this.$scope.component.getModuleForDisplay(module.uniqueId).then(onSuccess, onFailed); - } - } - - const componentInstances: Array = this.$scope.component.componentInstances || []; - (_.values(module.members)).forEach((memberId) => { - if (!(memberId in this.$scope.componentInstancesMap)) { - const compInstance = componentInstances.find((c) => c.uniqueId === memberId); - if (compInstance) { - this.$scope.componentInstancesMap[compInstance.uniqueId] = compInstance; - } - } - }); - }; - - this.$scope.updateHeatName = () => { - this.$scope.isLoading = true; - - let originalName:string = this.$scope.selectedModule.name; - - let onSuccess = (module:Module) => { - console.log("Module name updated:", module.name); - this.$scope.selectedModule.name = module.name; - this.$scope.isLoading = false; - }; - - let onFailed = () => { - this.$scope.isLoading = false; - this.$scope.selectedModule.name = originalName; - }; - - this.$scope.selectedModule.updateName(); - this.$scope.component.updateGroupMetadata(new DisplayModule(this.$scope.selectedModule)).then(onSuccess, onFailed); - }; - - this.$scope.openEditPropertyModal = (property:PropertyModel, filteredProperties:Array):void => { - this.ModalsHandler.openEditModulePropertyModal(property, this.$scope.component, this.$scope.selectedModule, filteredProperties).then(() => { - }); - } - } -} diff --git a/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy-view.html b/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy-view.html deleted file mode 100644 index 423cbcd1f0..0000000000 --- a/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy-view.html +++ /dev/null @@ -1,123 +0,0 @@ - - -
    - -
    - -
    -
    - - -
    {{component.name}}
    - -
    -
    - - -
    -
    - -
    -
    -
    {{componentInstancesMap[memberId].name}}
    -
    -
    -
    -
    -
    - - -
    -
    - - -
    -
    - -
    - -
    -
    - - -
    -
    - -
    -
    -
    {{componentInstancesMap[memberId].name}}
    -
    -
    -
    -
    -
    - -
    - -
    -
    -
    {{selectedModule.name}}
    -
    - -
    -
    -
    Module ID:
    {{selectedModule.groupUUID}}
    -
    Customization ID:
    {{selectedModule.customizationUUID}}
    -
    Invariant UUID:{{selectedModule.invariantUUID}}
    -
    Version: {{selectedModule.version}}
    -
    IsBase: {{selectedModule.isBase}}
    - -
    - -
    -
    -
    - {{property.name}} -
    -
    Type: {{property.type}}
    -
    Value: {{property.value}}
    -
    -
    - -
    -
    -
    {{artifact.artifactName}}
    -
    UUID: {{artifact.artifactUUID}}
    -
    Version: {{artifact.artifactVersion}}
    -
    -
    -
    -
    -
    -
    diff --git a/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy.less b/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy.less deleted file mode 100644 index dee0eeb38b..0000000000 --- a/catalog-ui/src/app/view-models/tabs/hierarchy/hierarchy.less +++ /dev/null @@ -1,101 +0,0 @@ -.hierarchy-tab{ - width: 100%; - .hierarchy-module-list-container{ - padding: 0px 20px 0px 20px; - } - .module-data-container{ - - width: 100%; - height: 100%; - background-color: #e6f6fb; - border: 1px solid #009fdb; - border-top: 4px solid #009fdb; - box-shadow: 0.3px 1px 2px rgba(24, 24, 25, 0.32); - - .module-data { - - .selectable; - .module-name { - .f-type._14_m; - width: 87%; - } - .f-type._14_r; - .f-color.a; - padding: 10px 0px 10px 0px; - margin: 0px 20px 0px 20px; - //border-bottom: 1px solid rgba(0, 159, 219, 0.6); - - .small-font{ - font-size: 12px; - } - } - - .list-item{ - padding: 10px 0px 10px 0px; - margin: 0px 20px 0px 20px; - &:not(.last){ - border-bottom: 1px solid rgba(0, 159, 219, 0.6); - } - } - - .artifact-data{ - .selectable; - .f-type._12_r; - .f-color.m; - .artifact-name { - .f-type._14_r; - font-weight: bold; - } - } - - .property-data{ - .property-name{ - width: 100%; - .f-type._14_m; - font-weight: 400; - color: @main_color_a; - } - .property-info{ - color: @func_color_s; - .f-type._14_r; - width: 100%; - } - } - - .module-text-overflow { - max-width: 240px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - //display: inline-block; - } - } - - .hierarchy-modules-list{ - .expand-collapse-title{ - .expand-collapse-title-text{ - max-width: 202px; - } - } - } - - .hierarchy-module-member-list { - overflow: hidden; - background-color: @main_color_p; - } - - .edit-name-container { - float: right; - border-left: 1px solid #5cc1e7; - height: 20px; - width: 12%; - - .sdc-edit-icon { - float: right; - cursor: pointer; - position: relative; - top: 4px; - right: 5px; - } - } -} diff --git a/catalog-ui/src/app/view-models/tutorial-end/tutorial-end.html b/catalog-ui/src/app/view-models/tutorial-end/tutorial-end.html deleted file mode 100644 index 3dffbb9a79..0000000000 --- a/catalog-ui/src/app/view-models/tutorial-end/tutorial-end.html +++ /dev/null @@ -1,26 +0,0 @@ - - -
    - -

    -

    -
    - - -
    -
    -
    diff --git a/catalog-ui/src/app/view-models/tutorial-end/tutorial-end.less b/catalog-ui/src/app/view-models/tutorial-end/tutorial-end.less deleted file mode 100644 index 30fa4f7e8b..0000000000 --- a/catalog-ui/src/app/view-models/tutorial-end/tutorial-end.less +++ /dev/null @@ -1,41 +0,0 @@ -.sdc-tutorial-end-page { - - .bg_s; - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - z-index: 999; - .opacity(0.8); - display: flex; - align-items: center; - - background-image: url('/assets/styles/images/welcome.png'); - background-repeat: no-repeat; - background-position: bottom left; - - .sdc-tutorial-end-page-main { - width: 600px; - height: 400px; - margin: 100px auto 100px auto; - padding: 80px; - } - - h2 { - .t_15; - margin: 0; - } - - .sdc-tutorial-end-page-description1 { - .c_2; - .opacity(0.8); - margin-top: 10px; - line-height: 22px; - } - - .w-sdc-btn-blue { - margin: 40px 10px 0 0; - } - -} diff --git a/catalog-ui/src/app/view-models/tutorial-end/tutorial-end.ts b/catalog-ui/src/app/view-models/tutorial-end/tutorial-end.ts deleted file mode 100644 index 5c4c4999e8..0000000000 --- a/catalog-ui/src/app/view-models/tutorial-end/tutorial-end.ts +++ /dev/null @@ -1,40 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; - -interface ITutorialEndViewModelScope extends ng.IScope { -} - -export class TutorialEndViewModel { - - static '$inject' = [ - '$scope' - ]; - - constructor(private $scope:ITutorialEndViewModelScope) { - this.init(); - } - - private init = ():void => { - - } - -} diff --git a/catalog-ui/src/app/view-models/welcome/welcome-view.html b/catalog-ui/src/app/view-models/welcome/welcome-view.html deleted file mode 100644 index c342741f22..0000000000 --- a/catalog-ui/src/app/view-models/welcome/welcome-view.html +++ /dev/null @@ -1,25 +0,0 @@ - - -
    -
    -
    -
    -
    -

    Welcome to SDC

    -
    -
    -
    diff --git a/catalog-ui/src/app/view-models/welcome/welcome-view.ts b/catalog-ui/src/app/view-models/welcome/welcome-view.ts deleted file mode 100644 index 5ed7159d79..0000000000 --- a/catalog-ui/src/app/view-models/welcome/welcome-view.ts +++ /dev/null @@ -1,81 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; - -export interface IWelcomeViewMode { - onCloseButtonClick():void; -} - -export class WelcomeViewModel { - - firstLoad:boolean = true; - alreadyAnimated:Array = []; - - static '$inject' = [ - '$scope', - '$state' - ]; - - constructor(private $scope:IWelcomeViewMode, - private $state:ng.ui.IStateService - ) { - this.init(); - this.initScope(); - window.setTimeout(():void => { - this.loadImages(():void=> { - window.setTimeout(():void =>{ - $(".sdc-welcome-new-page").addClass("animated fadeIn"); - },1000); - }); - },0); - } - - private initScope = ():void => { - let timeout = window.setTimeout(():void => { - this.$state.go("dashboard", {}); - }, 4000); - this.$scope.onCloseButtonClick = ():void => { - window.clearTimeout(timeout); - this.$state.go("dashboard", {}); - } - }; - - private init = ():void => { - let viewModelsHtmlBasePath:string = 'src/app/view-models/'; - $('body').keyup((e):void=> { - if (e.keyCode == 27) { // escape key maps to keycode `27` - this.$state.go('dashboard'); - } - }); - }; - - private loadImages = (callback:Function):void => { - let src = $('.sdc-welcome-wrapper').css('background-image'); - let url = src.match(/\((.*?)\)/)[1].replace(/('|")/g,''); - - let img = new Image(); - img.onload = function() { - callback(); - }; - img.src = url; - }; - -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/activity-log/activity-log.html b/catalog-ui/src/app/view-models/workspace/tabs/activity-log/activity-log.html deleted file mode 100644 index c5ab3cc110..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/activity-log/activity-log.html +++ /dev/null @@ -1,101 +0,0 @@ - - -
    - -
    - -
    - -
    -
    - - -
    -
    {{header.title}} - -
    -
    - - -
    - - - -
    - There are no logs to display -
    - - -
    - - -
    - {{item.dateFormat}} -
    - - -
    - {{item.ACTION}} -
    - - -
    - {{item.COMMENT}} -
    - - -
    - {{item.MODIFIER}} -
    - - -
    - {{item.STATUS}} - -
    - -
    - -
    -
    -
    -
    - -
    - - - - diff --git a/catalog-ui/src/app/view-models/workspace/tabs/activity-log/activity-log.less b/catalog-ui/src/app/view-models/workspace/tabs/activity-log/activity-log.less deleted file mode 100644 index 24f83ec503..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/activity-log/activity-log.less +++ /dev/null @@ -1,80 +0,0 @@ -.activity-log { - .title-wrapper { - display: flex; - justify-content: flex-end; - } - - .table-container-flex .table .body .scrollbar-container { - max-height: 448px; - } - - .view-mode { - background-color: @main_color_p; - } - - .table{ - height: 490px; - margin-bottom: 0; - } - - .table-container-flex { - margin-top: 10px; - - .flex-item:nth-child(1) { width: 200px; } - .flex-item:nth-child(2) { flex-grow: 20; } - .flex-item:nth-child(3) { flex-grow: 30; } - .flex-item:nth-child(4) { flex-grow: 20; } - .flex-item:nth-child(5) { width: 80px; } - - .success { - position: absolute; - top: 11px; - right: 20px; - .sprite-new; - .sdc-success; - } - - .error { - position: absolute; - top: 11px; - right: 20px; - .sprite-new; - .sdc-error; - } - - } - - .data-row { - position: relative; - } - - .top-search { - float: right; - position: relative; - - input.search-text { - .border-radius(2px); - width: 245px; - height: 32px; - line-height: 32px; - border: 1px solid @main_color_o; - margin: 0; - outline: none; - text-indent: 10px; - - &::-webkit-input-placeholder { font-style: italic; } /* Safari, Chrome and Opera */ - &:-moz-placeholder { font-style: italic; } /* Firefox 18- */ - &::-moz-placeholder { font-style: italic; } /* Firefox 19+ */ - &:-ms-input-placeholder { font-style: italic; } /* IE 10+ */ - &:-ms-input-placeholder { font-style: italic; } /* Edge */ - } - - .magnification { - position: absolute; - top: 10px; - right: 10px; - } - - } - -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/activity-log/activity-log.ts b/catalog-ui/src/app/view-models/workspace/tabs/activity-log/activity-log.ts deleted file mode 100644 index 452224a829..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/activity-log/activity-log.ts +++ /dev/null @@ -1,123 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import * as _ from "lodash"; -import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model"; -import {Activity} from "app/models"; -import {ActivityLogService} from "app/services"; - -export interface IActivityLogViewModelScope extends IWorkspaceViewModelScope { - activityDateArray:Array; //this is in order to sort the dates - activityLog:Array; - preVersion:string; - - tableHeadersList:Array; - reverse:boolean; - sortBy:string; - searchBind:string; - - getActivityLog(uniqueId:string):void; - onVersionChanged(version:any):void; - parseAction(action:string):string; - sort(sortBy:string):void; -} - -export class ActivityLogViewModel { - - static '$inject' = [ - '$scope', - '$state', - 'Sdc.Services.ActivityLogService' - ]; - - constructor(private $scope:IActivityLogViewModelScope, - private $state:ng.ui.IStateService, - private activityLogService:ActivityLogService) { - - this.initScope(); - this.$scope.setValidState(true); - this.initSortedTableScope(); - - // Set default sorting - this.$scope.sortBy = 'logDate'; - } - - private initScope():void { - - this.$scope.preVersion = this.$scope.component.version; - - this.$scope.onVersionChanged = (version:any):void => { - if (version.versionNumber != this.$scope.component.version) { - this.$scope.isLoading = true; - this.$scope.getActivityLog(version.versionId); - } - }; - - this.$scope.getActivityLog = (uniqueId:any):void => { - - let onError = (response) => { - this.$scope.isLoading = false; - console.info('onFaild', response); - - }; - - let onSuccess = (response:Array) => { - this.$scope.activityLog = _.sortBy(response, function (o) { - return o.TIMESTAMP; - }); //response; // - this.$scope.isLoading = false; - }; - - this.$scope.isLoading = true; - if (this.$scope.component.isResource()) { - this.activityLogService.getActivityLogService('resources', uniqueId).then(onSuccess, onError); - } - if (this.$scope.component.isService()) { - this.activityLogService.getActivityLogService('services', uniqueId).then(onSuccess, onError); - } - - }; - - if (!this.$scope.activityLog || this.$scope.preVersion != this.$scope.component.version) { - this.$scope.getActivityLog(this.$scope.component.uniqueId); - } - - this.$scope.parseAction = (action:string) => { - return action ? action.split(/(?=[A-Z])/).join(' ') : ''; - }; - - } - - private initSortedTableScope = ():void => { - this.$scope.tableHeadersList = [ - {title: 'Date', property: 'dateFormat'}, - {title: 'Action', property: 'ACTION'}, - {title: 'Comment', property: 'COMMENT'}, - {title: 'Username', property: 'MODIFIER'}, - {title: 'Status', property: 'STATUS'} - ]; - - this.$scope.sort = (sortBy:string):void => { - this.$scope.reverse = (this.$scope.sortBy === sortBy) ? !this.$scope.reverse : false; - this.$scope.sortBy = sortBy; - }; - }; -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes-view-model.ts deleted file mode 100644 index 312a663e8f..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes-view-model.ts +++ /dev/null @@ -1,99 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model"; -import {Component, AttributeModel} from "app/models"; -import {ModalsHandler} from "app/utils"; -import {ComponentServiceNg2} from "../../../../ng2/services/component-services/component.service"; -import {ComponentGenericResponse} from "../../../../ng2/services/responses/component-generic-response"; - -interface IAttributesViewModelScope extends IWorkspaceViewModelScope { - tableHeadersList:Array; - reverse:boolean; - sortBy:string; - - addOrUpdateAttribute(attribute?:AttributeModel):void; - delete(attribute:AttributeModel):void; - sort(sortBy:string):void; -} - -export class AttributesViewModel { - - static '$inject' = [ - '$scope', - '$filter', - '$uibModal', - 'ModalsHandler', - 'ComponentServiceNg2' - ]; - - - constructor(private $scope:IAttributesViewModelScope, - private $filter:ng.IFilterService, - private $uibModal:ng.ui.bootstrap.IModalService, - private ModalsHandler:ModalsHandler, - private ComponentServiceNg2: ComponentServiceNg2) { - - this.initComponentAttributes(); - } - - private initComponentAttributes = () => { - if(this.$scope.component.attributes) { - this.initScope(); - } else { - this.ComponentServiceNg2.getComponentAttributes(this.$scope.component).subscribe((response:ComponentGenericResponse) => { - this.$scope.component.attributes = response.attributes; - this.initScope(); - }); - } - } - - - private initScope = ():void => { - - this.$scope.sortBy = 'name'; - this.$scope.reverse = false; - this.$scope.setValidState(true); - this.$scope.tableHeadersList = [ - {title: 'Name', property: 'name'}, - {title: 'Type', property: 'type'}, - {title: 'Default Value', property: 'defaultValue'} - ]; - this.$scope.sort = (sortBy:string):void => { - this.$scope.reverse = (this.$scope.sortBy === sortBy) ? !this.$scope.reverse : false; - this.$scope.sortBy = sortBy; - }; - - this.$scope.addOrUpdateAttribute = (attribute?:AttributeModel):void => { - this.ModalsHandler.openEditAttributeModal(attribute ? attribute : new AttributeModel(), this.$scope.component); - }; - - this.$scope.delete = (attribute:AttributeModel):void => { - - let onOk = ():void => { - this.$scope.component.deleteAttribute(attribute.uniqueId); - }; - let title:string = this.$filter('translate')("ATTRIBUTE_VIEW_DELETE_MODAL_TITLE"); - let message:string = this.$filter('translate')("ATTRIBUTE_VIEW_DELETE_MODAL_TEXT", "{'name': '" + attribute.name + "'}"); - this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk); - }; - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes-view.html b/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes-view.html deleted file mode 100644 index 675ae0c5c6..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes-view.html +++ /dev/null @@ -1,68 +0,0 @@ - - -
    -
    Add
    -
    -
    -
    -
    {{header.title}} - -
    -
    - -
    - -
    - -
    - There are no attributes to display
    - click here to add one - -
    -
    - -
    - - {{attribute.name}} - -
    - -
    - -
    - -
    - -
    - - -
    -
    -
    -
    -
    -
    - -
    -
    - -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes.less b/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes.less deleted file mode 100644 index 932daa167d..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/attributes/attributes.less +++ /dev/null @@ -1,54 +0,0 @@ -.workspace-attributes { - - width: 93%; - display: inline-block; - .w-sdc-classic-btn { - float: right; - margin-bottom: 10px; - } - - .table{ - height:490px; - margin-bottom: 0; - } - - .table-container-flex { - margin-top: 0; - - .text{ - overflow: hidden; - text-overflow: ellipsis; - display: inline-block; - white-space: nowrap; - } - - .flex-item:nth-child(1) { - flex-grow: 15; - - .hand; - span.table-arrow { - margin-right: 7px; - } - } - - .flex-item:nth-child(2) { - flex-grow: 6; - } - - .flex-item:nth-child(3) { - flex-grow: 9; - } - - .flex-item:nth-child(4) { - flex-grow: 3; - padding-top: 10px; - } - - .flex-item:nth-child(5) { - flex-grow: 1; - - } - - } - -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/composition-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/composition/composition-view-model.ts deleted file mode 100644 index 2270a7b06e..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/composition-view-model.ts +++ /dev/null @@ -1,501 +0,0 @@ -/*- - * ============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========================================================= - */ -'use strict'; -import * as _ from "lodash"; -import { Component, ComponentInstance, IAppMenu, Requirement, Capability, ButtonModel } from "app/models"; -import { SharingService, CacheService, EventListenerService, LeftPaletteLoaderService } from "app/services"; -import { ModalsHandler, GRAPH_EVENTS, ComponentFactory, ChangeLifecycleStateHandler, MenuHandler, EVENTS, ComponentInstanceFactory } from "app/utils"; -import { IWorkspaceViewModelScope } from "../../workspace-view-model"; -import { ComponentGenericResponse } from "app/ng2/services/responses/component-generic-response"; -import { Resource } from "app/models/components/resource"; -import { ResourceType, ComponentType } from "app/utils/constants"; -import { ComponentServiceFactoryNg2 } from "app/ng2/services/component-services/component.service.factory"; -import { ServiceGenericResponse } from "app/ng2/services/responses/service-generic-response"; -import { Service } from "app/models/components/service"; -import { ZoneInstance } from "app/models/graph/zones/zone-instance"; -import { ComponentServiceNg2 } from "app/ng2/services/component-services/component.service"; -import { ModalService as ModalServiceSdcUI} from "sdc-ui/lib/angular/modals/modal.service" -import { IModalConfig, IModalButtonComponent } from "sdc-ui/lib/angular/modals/models/modal-config"; -import { ValueEditComponent } from "app/ng2/components/ui/forms/value-edit/value-edit.component"; -import { UnsavedChangesComponent } from "../../../../ng2/components/ui/forms/unsaved-changes/unsaved-changes.component"; -import { ModalButtonComponent } from "sdc-ui/lib/angular/components"; - - - -export interface ICompositionViewModelScope extends IWorkspaceViewModelScope { - - currentComponent:Component; - - //Added for now, in the future need to remove and use only id and type to pass to tabs. - selectedComponent: Component; - selectedZoneInstance: ZoneInstance; - - componentInstanceNames: Array; - isLoading:boolean; - graphApi:any; - sharingService:SharingService; - sdcMenu:IAppMenu; - version:string; - isViewOnly:boolean; - isCanvasTagging:boolean; - isLoadingRightPanel:boolean; - disabledTabs:boolean; - openVersionChangeModal(pathsToDelete:string[]):ng.IPromise; - onComponentInstanceVersionChange(component:Component); - isComponentInstanceSelected():boolean; - updateSelectedComponent():void; - openUpdateModal(); - deleteSelectedComponentInstance():void; - onBackgroundClick():void; - setSelectedInstance(componentInstance:ComponentInstance):void; - setSelectedZoneInstance(zoneInstance: ZoneInstance):void; - changeZoneInstanceName(newName:string):void; - printScreen():void; - isPNF():boolean; - isConfiguration():boolean; - preventMoveTab(state: boolean):void; - registerCreateInstanceEvent(callback: Function):void; - unregisterCreateInstanceEvent():void; - registerChangeComponentInstanceNameEvent(callback: Function):void; - unregisterChangeComponentInstanceNameEvent():void; - - ComponentServiceNg2:ComponentServiceNg2, - cacheComponentsInstancesFullData:Component; -} - -export class CompositionViewModel { - - static '$inject' = [ - '$scope', - '$log', - 'sdcMenu', - 'MenuHandler', - '$uibModal', - '$state', - 'Sdc.Services.SharingService', - '$filter', - 'Sdc.Services.CacheService', - 'ComponentFactory', - 'ChangeLifecycleStateHandler', - 'LeftPaletteLoaderService', - 'ModalsHandler', - 'ModalServiceSdcUI', - 'EventListenerService', - 'ComponentServiceFactoryNg2', - 'ComponentServiceNg2', - 'Notification' - ]; - - constructor(private $scope:ICompositionViewModelScope, - private $log:ng.ILogService, - private sdcMenu:IAppMenu, - private MenuHandler:MenuHandler, - private $uibModal:ng.ui.bootstrap.IModalService, - private $state:ng.ui.IStateService, - private sharingService:SharingService, - private $filter:ng.IFilterService, - private cacheService:CacheService, - private ComponentFactory:ComponentFactory, - private ChangeLifecycleStateHandler:ChangeLifecycleStateHandler, - private LeftPaletteLoaderService:LeftPaletteLoaderService, - private ModalsHandler:ModalsHandler, - private ModalServiceSdcUI: ModalServiceSdcUI, - private eventListenerService:EventListenerService, - private ComponentServiceFactoryNg2: ComponentServiceFactoryNg2, - private ComponentServiceNg2:ComponentServiceNg2, - private Notification:any - ) { - - this.$scope.setValidState(true); - this.initScope(); - this.initGraphData(); - this.registerGraphEvents(this.$scope); - } - - - private initGraphData = ():void => { - if(!this.hasCompositionGraphData(this.$scope.component)) { - this.$scope.isLoading = true; - let service = this.ComponentServiceFactoryNg2.getComponentService(this.$scope.component); - service.getComponentCompositionData(this.$scope.component).subscribe((response:ComponentGenericResponse) => { - if (this.$scope.component.isService()) { - ( this.$scope.component).forwardingPaths = (response).forwardingPaths; - } - this.$scope.component.componentInstances = response.componentInstances || []; - this.$scope.component.componentInstancesRelations = response.componentInstancesRelations || []; - this.$scope.component.policies = response.policies || []; - this.$scope.component.groupInstances = response.groupInstances || []; - this.$scope.isLoading = false; - this.initComponent(); - this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_COMPOSITION_GRAPH_DATA_LOADED); - }); - } else { - this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_COMPOSITION_GRAPH_DATA_LOADED); - } - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_COMPOSITION_GRAPH_DATA_LOADED); - }; - - private hasCompositionGraphData = (component:Component):boolean => { - return !!(component.componentInstances && component.componentInstancesRelations && component.policies && component.groupInstances); - }; - - private cacheComponentsInstancesFullData:Array; - - private initComponent = ():void => { - this.$scope.currentComponent = this.$scope.component; - this.$scope.selectedComponent = this.$scope.currentComponent; - this.$scope.selectedZoneInstance = null; - this.updateUuidMap(); - this.$scope.isViewOnly = this.$scope.isViewMode(); - }; - - private registerGraphEvents = (scope:ICompositionViewModelScope):void => { - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_NODE_SELECTED, scope.setSelectedInstance); - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_ZONE_INSTANCE_SELECTED, scope.setSelectedZoneInstance); - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED, scope.onBackgroundClick); - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_CANVAS_TAG_START, () => { - scope.isCanvasTagging = true; - this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, true, this.showUnsavedChangesAlert); - }); - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_CANVAS_TAG_END, () => { - scope.isCanvasTagging = false; - this.resetUnsavedChanges(); - }); - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_ZONE_INSTANCE_NAME_CHANGED, scope.changeZoneInstanceName); - this.eventListenerService.registerObserverCallback(EVENTS.UPDATE_PANEL, this.removeSelectedZoneInstance); - }; - - private showUnsavedChangesAlert = (afterSave?:Function):Promise => { - let deferred = new Promise((resolve, reject)=> { - const modal = this.ModalServiceSdcUI.openCustomModal( - { - title: "Unsaved Changes", - size: 'sm', - type: 'custom', - - buttons: [ - {id: 'cancelButton', text: 'Cancel', type: 'secondary', size: 'xsm', closeModal: true, callback: () => reject()}, - {id: 'discardButton', text: 'Discard', type: 'secondary', size: 'xsm', closeModal: true, callback: () => { this.resetUnsavedChanges(); resolve()}}, - {id: 'saveButton', text: 'Save', type: 'primary', size: 'xsm', closeModal: true, callback: () => { reject(); this.saveUnsavedChanges(afterSave); }} - ] as IModalButtonComponent[] - }, UnsavedChangesComponent, { isValidChangedData: true}); - }); - - return deferred; - } - - private unRegisterGraphEvents = (scope: ICompositionViewModelScope):void => { - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_NODE_SELECTED, scope.setSelectedInstance); - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_ZONE_INSTANCE_SELECTED, scope.setSelectedZoneInstance); - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED, scope.onBackgroundClick); - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_CANVAS_TAG_START); - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_CANVAS_TAG_END); - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_ZONE_INSTANCE_NAME_CHANGED, scope.changeZoneInstanceName); - this.eventListenerService.unRegisterObserver(EVENTS.UPDATE_PANEL, this.removeSelectedZoneInstance); - - }; - - private resetUnsavedChanges = () => { - this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false); - } - - private saveUnsavedChanges = (afterSaveFunction?:Function):void => { - this.$scope.selectedZoneInstance.forceSave.next(afterSaveFunction); - this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false); - } - - private openUpdateComponentInstanceNameModal = ():void => { - - let modalConfig:IModalConfig = { - title: "Edit Name", - size: "sm", - type: "custom", - testId: "renameInstanceModal", - buttons: [ - {id: 'saveButton', text: 'OK', size: 'xsm', callback: this.saveInstanceName, closeModal: false}, - {id: 'cancelButton', text: 'Cancel', size: 'sm', closeModal: true} - ] - }; - - this.ModalServiceSdcUI.openCustomModal(modalConfig, ValueEditComponent, {name: this.$scope.currentComponent.selectedInstance.name, validityChangedCallback: this.enableOrDisableSaveButton}); - - }; - - - private enableOrDisableSaveButton = (shouldEnable: boolean): void => { - let saveButton: ModalButtonComponent = this.ModalServiceSdcUI.getCurrentInstance().getButtonById('saveButton'); - saveButton.disabled = !shouldEnable; - } - - private saveInstanceName = () => { - let currentModal = this.ModalServiceSdcUI.getCurrentInstance(); - let nameFromModal:string = currentModal.innerModalContent.instance.name; - - if(nameFromModal != this.$scope.currentComponent.selectedInstance.name){ - currentModal.buttons[0].disabled = true; - let componentInstanceModel:ComponentInstance = ComponentInstanceFactory.createComponentInstance(this.$scope.currentComponent.selectedInstance); - componentInstanceModel.name = nameFromModal; - - let onFailed = (error) => { - currentModal.buttons[0].disabled = false; - }; - let onSuccess = (componentInstance:ComponentInstance) => { - - this.$scope.currentComponent.selectedInstance.name = componentInstance.name; - //update requirements and capabilities owner name - _.forEach(this.$scope.currentComponent.selectedInstance.requirements, (requirementsArray:Array) => { - _.forEach(requirementsArray, (requirement:Requirement):void => { - requirement.ownerName = componentInstance.name; - }); - }); - - _.forEach(this.$scope.currentComponent.selectedInstance.capabilities, (capabilitiesArray:Array) => { - _.forEach(capabilitiesArray, (capability:Capability):void => { - capability.ownerName = componentInstance.name; - }); - }); - this.ModalServiceSdcUI.closeModal(); - this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_COMPONENT_INSTANCE_NAME_CHANGED, this.$scope.currentComponent.selectedInstance); - }; - - this.$scope.currentComponent.updateComponentInstance(componentInstanceModel).then(onSuccess, onFailed); - } else { - this.ModalServiceSdcUI.closeModal(); - } - - }; - - private removeSelectedComponentInstance = ():void => { - this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_DELETE_COMPONENT_INSTANCE, this.$scope.currentComponent.selectedInstance) - this.$scope.currentComponent.selectedInstance = null; - this.$scope.selectedComponent = this.$scope.currentComponent; - }; - - private removeSelectedZoneInstance = ():void => { - this.$scope.currentComponent.selectedInstance = null; - this.$scope.selectedZoneInstance = null; - this.$scope.selectedComponent = this.$scope.currentComponent; - } - - private updateUuidMap = ():void => { - /** - * In case user press F5, the page is refreshed and this.sharingService.currentEntity will be undefined, - * but after loadService or loadResource this.sharingService.currentEntity will be defined. - * Need to update the uuidMap with the new resource or service. - */ - this.sharingService.addUuidValue(this.$scope.currentComponent.uniqueId, this.$scope.currentComponent.uuid); - }; - - private initScope = ():void => { - this.$scope.sharingService = this.sharingService; - this.$scope.sdcMenu = this.sdcMenu; - this.$scope.isLoading = false; - this.$scope.isLoadingRightPanel = false; - this.$scope.isCanvasTagging = false; - this.$scope.graphApi = {}; - this.$scope.version = this.cacheService.get('version'); - this.initComponent(); - - this.cacheComponentsInstancesFullData = new Array(); - - this.$scope.isComponentInstanceSelected = ():boolean => { - return this.$scope.currentComponent && this.$scope.currentComponent.selectedInstance != undefined && this.$scope.currentComponent.selectedInstance != null; - }; - - this.$scope.$on('$destroy', () => { - this.unRegisterGraphEvents(this.$scope); - }) - - this.$scope.restoreComponent = ():void => { - this.ComponentServiceNg2.restoreComponent(this.$scope.selectedComponent.componentType, this.$scope.selectedComponent.uniqueId).subscribe(() => { - this.Notification.success({ - message: '<' + this.$scope.component.name + '> ' + this.$filter('translate')("ARCHIVE_SUCCESS_MESSAGE_TEXT"), - title: this.$filter('translate')("ARCHIVE_SUCCESS_MESSAGE_TITLE") - }); - this.$scope.selectedComponent.archived = false; - } - ) - }; - - this.$scope.updateSelectedComponent = ():void => { - if (this.$scope.currentComponent.selectedInstance) { - let parentComponentUid = this.$scope.currentComponent.selectedInstance.componentUid - if(this.$scope.currentComponent.selectedInstance.originType === ComponentType.SERVICE_PROXY){ - parentComponentUid = this.$scope.currentComponent.selectedInstance.sourceModelUid; - } - let componentParent = _.find(this.cacheComponentsInstancesFullData, (component) => { - return component.uniqueId === parentComponentUid; - }); - if (componentParent) { - this.$scope.selectedComponent = componentParent; - } - else { - try { - let onSuccess = (component:Component) => { - this.$scope.isLoadingRightPanel = false; - this.$scope.selectedComponent = component; - this.cacheComponentsInstancesFullData.push(component); - }; - let onError = (component:Component) => { - console.log("Error updating selected component"); - this.$scope.isLoadingRightPanel = false; - }; - this.ComponentFactory.getComponentFromServer(this.$scope.currentComponent.selectedInstance.originType, parentComponentUid).then(onSuccess, onError); - } catch (e) { - console.log("Error updating selected component", e); - this.$scope.isLoadingRightPanel = false; - } - } - } - else { - - this.$scope.selectedComponent = this.$scope.currentComponent; - } - }; - - this.$scope.setSelectedInstance = (selectedComponent:ComponentInstance):void => { - - this.$log.debug('composition-view-model::onNodeSelected:: with id: ' + selectedComponent.uniqueId); - this.$scope.currentComponent.setSelectedInstance(selectedComponent); - this.$scope.selectedZoneInstance = null; - this.$scope.updateSelectedComponent(); - - if (this.$state.current.name === 'workspace.composition.api') { - this.$state.go('workspace.composition.details'); - } - if(!selectedComponent.isServiceProxy() && (this.$state.current.name === 'workspace.composition.consumption' || this.$state.current.name === 'workspace.composition.dependencies')) { - this.$state.go('workspace.composition.details'); - } - }; - - this.$scope.setSelectedZoneInstance = (zoneInstance: ZoneInstance): void => { - this.$scope.currentComponent.selectedInstance = null; - this.$scope.selectedZoneInstance = zoneInstance; - }; - - this.$scope.onBackgroundClick = ():void => { - this.$scope.currentComponent.selectedInstance = null; - this.$scope.selectedZoneInstance = null; - this.$scope.selectedComponent = this.$scope.currentComponent; - - if (this.$state.current.name === 'workspace.composition.api' || this.$state.current.name === 'workspace.composition.consumption' || this.$state.current.name === 'workspace.composition.dependencies') { - this.$state.go('workspace.composition.details'); - } - - if(this.$scope.selectedComponent.isService() && this.$state.current.name === 'workspace.composition.relations'){ - this.$state.go('workspace.composition.api'); - } - }; - - this.$scope.openUpdateModal = ():void => { - this.openUpdateComponentInstanceNameModal(); - }; - - this.$scope.changeZoneInstanceName = (newName:string):void => { - this.$scope.selectedZoneInstance.instanceData.name = newName; - }; - - this.$scope.deleteSelectedComponentInstance = ():void => { - const {currentComponent} = this.$scope; - const {title, message} = this.$scope.sdcMenu.alertMessages['deleteInstance']; - let modalText = message.format([currentComponent.selectedInstance.name]); - - if (currentComponent.isService()) { - const {forwardingPaths} = (currentComponent); - const instanceId = currentComponent.selectedInstance.uniqueId; - - const relatedPaths = _.filter(forwardingPaths, forwardingPath => { - const pathElements = forwardingPath.pathElements.listToscaDataDefinition; - return pathElements.find(path => path.fromNode === instanceId || path.toNode === instanceId); - }); - - if (relatedPaths.length) { - const pathNames = _.map(relatedPaths, path => path.name).join(', '); - modalText += `

    The following service paths will be erased: ${pathNames}

    `; - } - } - this.ModalServiceSdcUI.openAlertModal(title, modalText, "OK", this.removeSelectedComponentInstance, "deleteInstanceModal"); - }; - - this.$scope.openVersionChangeModal = (pathsToDelete:string[]):ng.IPromise => { - const {currentComponent} = this.$scope; - const {forwardingPaths} = currentComponent; - - const relatedPaths = _.filter(forwardingPaths, path => - _.find(pathsToDelete, id => - path.uniqueId === id - ) - ).map(path => path.name); - const pathNames = _.join(relatedPaths, ', ') || 'none'; - - const {title, message} = this.$scope.sdcMenu.alertMessages['upgradeInstance']; - return this.ModalsHandler.openConfirmationModal(title, message.format([pathNames]), false); - }; - - this.$scope.onComponentInstanceVersionChange = (component:Component):void => { - let onChange = () => { - this.$scope.currentComponent = component; - this.$scope.setComponent(this.$scope.currentComponent); - this.$scope.updateSelectedComponent(); - this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_VERSION_CHANGED, this.$scope.currentComponent); - }; - - if (component.isService()) { - const service = this.ComponentServiceFactoryNg2.getComponentService(component); - service.getComponentCompositionData(component).subscribe((response:ServiceGenericResponse) => { - (component).forwardingPaths = response.forwardingPaths; - onChange(); - }); - } else { - onChange(); - } - }; - - this.$scope.isPNF = (): boolean => { - return this.$scope.selectedComponent.isResource() && (this.$scope.selectedComponent).resourceType === ResourceType.PNF; - }; - - this.$scope.isConfiguration = (): boolean => { - return this.$scope.selectedComponent.isResource() && (this.$scope.selectedComponent).resourceType === ResourceType.CONFIGURATION; - }; - - this.$scope.preventMoveTab = (state: boolean): void => { - this.$scope.disabledTabs = state; - }; - - this.eventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.$scope.reload); - - this.$scope.registerCreateInstanceEvent = (callback: Function): void => { - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_CREATE_COMPONENT_INSTANCE, callback); - }; - - this.$scope.unregisterCreateInstanceEvent = (): void => { - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_CREATE_COMPONENT_INSTANCE); - }; - - this.$scope.registerChangeComponentInstanceNameEvent = (callback: Function): void => { - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_COMPONENT_INSTANCE_NAME_CHANGED, callback); - }; - - this.$scope.unregisterChangeComponentInstanceNameEvent = (): void => { - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_COMPONENT_INSTANCE_NAME_CHANGED); - }; - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/composition-view.html b/catalog-ui/src/app/view-models/workspace/tabs/composition/composition-view.html deleted file mode 100644 index c2d6007edc..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/composition-view.html +++ /dev/null @@ -1,159 +0,0 @@ - - -
    - -
    - - - - - -
    - -
    - -
    - -
    - -
    - -
    -
    -
    -
    -
    -
    - - -
    - -
    -
    - -
    - - - - - - - - - - - - - - -
    -
    - -
    - - - - -
    - - - -
    - - - -
    -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/composition.less b/catalog-ui/src/app/view-models/workspace/tabs/composition/composition.less deleted file mode 100644 index f37a492572..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/composition.less +++ /dev/null @@ -1,955 +0,0 @@ - .i-sdc-designer-leftbar-section-popup-panel { - position: absolute; - display: inline-block; - background-color: white; - border: solid 1px #d2d2d2; - border-top: solid 3px #13a7df; - width: 140px; - height: 40px; - z-index: 10000; - } - - .i-sdc-designer-leftbar-section-popup-panel-group { - padding-left: 8px; - padding-top: 8px; - } - - .i-sdc-designer-leftbar-section-popup-panel-plus { - border-radius: 50%; - color: white; - background-color: #13a7df; - width: 20px; - text-align: center; - display: inline-block; - cursor: pointer; - } - - .i-sdc-designer-leftbar-section-popup-panel-title { - padding-left: 10px; - display: inline-block; - } - -.composition{ - .sdc-workspace-container{ - .w-sdc-main-container{ - .w-sdc-main-right-container{ - left:0; - //overflow-y: scroll; - .sdc-workspace-top-bar { - padding-left: 295px; - .not-latest{ - left: 270px; - } - } - .w-sdc-main-container-body-content{ - padding: 0 0 0 247px; - } - - > div:first-child{ - padding: 0; - } - } - } - } - - .custom-modal { - /* Hack solution to hide canvas tooltips under modals */ - z-index: 20000 !important; - } -} - -.workspace-composition { - height:100%; - display: block; - text-align: left; - align-items: left; - padding: 0; - - - - // --------------------------------------------------------------------------------------------------- - // Sidebar - // --------------------------------------------------------------------------------------------------- - - - - .w-sdc-designer-sidebar-toggle { - background-color: @main_color_p; - border-left: 1px solid @main_color_o; - border-bottom: 1px solid @main_color_o; - height: 21px; - position: absolute; - right: 0; - top: 53px; - width: 17px; - transition: right 0.2s; - z-index: 10; - .box-shadow(-1px 1px 3px 0 @main_color_n); - - &.active { - right: 302px; - .w-sdc-designer-sidebar-toggle-icon{ - transform: rotate(180deg); - } - } - - } - - .w-sdc-designer-sidebar-toggle-icon { - margin-left: 6px; - margin-top: 6px; - } - - .w-sdc-designer-sidebar { - background-color:@main_color_p ; - .noselect; - bottom: 0; - position: fixed; - right: -302px; - width: 302px; - top: 103px; - transition: right 0.2s; - z-index: 9; - .box-shadow(-7px -3px 6px -8px @main_color_n); - - } - - .w-sdc-designer-sidebar-toggle.active + .w-sdc-designer-sidebar { - right: 0; - - } - - .w-sdc-designer-sidebar-head { - padding: 36px 30px 30px 30px; - height: 120px; - } - - .w-sdc-designer-sidebar-logo-ph { - display: inline-block; - vertical-align: middle; - line-height: 60px; - height: 60px; - } - - .w-sdc-designer-sidebar-logo { - .g_6; - display: inline-block; - margin-left: 10px; - font-weight: 500; - } - - .w-sdc-designer-sidebar-logo-title { - .s_16_r; - .selectable; - vertical-align: middle; - text-overflow: ellipsis; - max-width: 167px; - display: inline-block; - white-space: nowrap; - overflow: hidden; - } - - .w-sdc-designer-update-resource-icon { - .hand; - position: absolute; - right: 20px; - top: 10px; - } - - .w-sdc-designer-delete-resource-icon { - .hand; - position: absolute; - right: 40px; - top: 10px; - } - - .w-sdc-designer-restore-button { - .hand; - position:absolute; - right: 20px; - top:10px; - width:65px; - } - .w-sdc-designer-sidebar-tabs { - .bg_c; - } - - .w-sdc-designer-sidebar-tabs::after { - clear: both; - content: ''; - display: table; - } - - .i-sdc-designer-sidebar-tab { - background-color: @main_color_p; - border: 1px solid @tlv_color_u;; - border-left: none; - display: inline-block; - float: left; - height: 36px; - padding-top: 9px; - text-align: center; - width: 60px; - .hand; - - &:focus { - outline: none; - } - &.tab-disabled { - /* .disabled; */ - } - &.active, &:hover:enabled { - background-color: @tlv_color_u; - .i-sdc-designer-sidebar-tab-icon { - opacity: 1; - - - } - - } - - div& { - padding-top: 0; - } - /*for tooltip on disabled buttons*/ - } - - .i-sdc-designer-sidebar-tab-icon { - margin-top: 5px ; - &.import-icon { - transform: rotate(270deg); - } - // opacity: .4; - } - - .w-sdc-designer-sidebar-tab-content { - .perfect-scrollbar; - height: 100%; - } - - .w-sdc-designer-sidebar-tab-content-view { - position: absolute; - top: 156px; - bottom: 0; - width: 100%; - padding-bottom: 10px; - - } - - .w-sdc-designer-sidebar-section { - } - - .w-sdc-designer-sidebar-section-title { - .m_14_m; - background-color: @tlv_color_u; - .hand; - clear: both; - height: 32px; - line-height: 32px; - margin-top: 1px; - padding: 0 10px 0 20px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - position: relative; - width: 100%; - display: block; - - &.expanded { - .w-sdc-designer-sidebar-section-title-icon { - transform: rotate(180deg); - } - } - } - - .w-sdc-designer-sidebar-section-title-text { - max-width: 240px; - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - position: relative; - } - - .w-sdc-designer-sidebar-section-title-icon { - .hand; - .sprite-new; - .arrow-up; - right: 16px; - top: 13px; - transition: .3s all; - position: absolute; - } - - .w-sdc-designer-sidebar-section-content { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - - .w-sdc-designer-sidebar-section-title { - text-transform: uppercase; - } - - .w-sdc-designer-sidebar-section-title + .w-sdc-designer-sidebar-section-content { - margin: 0 auto; - } - - .w-sdc-designer-sidebar-section-title.expanded + .w-sdc-designer-sidebar-section-content { - margin: 0 auto 1px; - - } - - .i-sdc-designer-sidebar-section-content-item { - .b_7; - font-size: 13px; - margin-bottom: 5px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - //max-width: 250px; - - &.description { - margin-top: 28px; - white-space: normal; - word-wrap: break-word; - } - } - - .i-sdc-designer-sidebar-section-content-item-tag { - .g_7; - .bg_c; - border-radius: 4px; - //fix long name for firefox: - display: block; - float: left; - line-height: 25px; - margin: 0 4px 6px 0; - min-width: 50px; - padding: 0 9px; - text-align: center; - max-width: 280px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - .w-sdc-designer-sidebar-section-footer { - margin-top: 10px; - text-align: center; - width: 100%; - } - - - - .w-sdc-designer-sidebar-section-footer-action { - width: 180px; - margin-top: 10px; - } - - //////////////////////Relationship - .w-sdc-designer-sidebar-section-requirements { - border-bottom: 1px solid @color_e; - margin: 0 13px 20px 13px; - padding: 15px 0 0; - } - - .w-sdc-designer-sidebar-section-requirements-item { - margin-bottom: 20px; - } - - .w-sdc-designer-sidebar-section-requirements-label { - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - vertical-align: middle; - white-space: nowrap; - width: 102px; - } - - .w-sdc-designer-sidebar-section-requirements-select { - border: 1px solid @color_e; - min-height: 30px; - padding: 4px 13px; - width: 168px; - } - - //////////////////////Properties - .i-sdc-designer-sidebar-section-content-item-property-and-attribute { - .b_7; - border-bottom: 1px solid @color_e; - min-height: 72px; - padding: 15px 10px 10px 18px; - position: relative; - - &:first-child { - //margin-top: -18px; - } - - &:hover { - // .bg_c_hover; - .bg_c; - transition: all .3s; - - .i-sdc-designer-sidebar-section-content-item-button { - display: block; - } - } - } - - .i-sdc-designer-sidebar-section-content-item-property-and-attribute-label { - overflow: hidden; - text-overflow: ellipsis; - max-width: 200px; - white-space: nowrap; - display: inline-block; - &:hover { - .a_7; - } - } - - .i-sdc-designer-sidebar-section-content-item-property-value { - overflow: hidden; - text-overflow: ellipsis; - max-width: 200px; - display: inline-block; - white-space: nowrap; - - } - - .i-sdc-designer-sidebar-section-content-item-property-label-value { - } - - .i-sdc-designer-sidebar-section-content-item-button { - display: none; - position: absolute; - top: 25px; - - &.update { - background-color: transparent; - border: 0; - right: 60px; - } - - &.delete { - background-color: transparent; - border: 0; - right: 13px; - } - - &.download { - background-color: transparent; - border: 0; - right: 35px; - } - - &.download-env { - background-color: transparent; - border: 0; - right: 35px; - margin-top: 65px; - } - - &.update-env { - background-color: transparent; - border: 0; - right: 15px; - margin-top: 65px; - } - - &.attach { - background-color: transparent; - border: 0; - right: 15px; - } - } - - // --------------------------------------------------------------------------------------------------- - // Canvas - // --------------------------------------------------------------------------------------------------- - .w-sdc-designer-canvas { - height:100%; - .noselect; - .bg_c; - bottom: 0; - // position: fixed; - //right: 0; - //left: 240px; - //top: 94px; - .view-mode{ - background-color: #f8f8f8; - border:0; - } - } - - .w-sdc-designer-canvas.sidebaractive { - //right: 300px; - } - - .w-sdc-designer-element { - .hand; - width: 200px; - height: 100px; - position: absolute; - text-align: center; - top: 50%; - margin-top: -200px; - left: 50%; - margin-left: -50px; - } - - .w-sdc-designer-resource-label { - .q_7; - } - - .w-sdc-designer-resource-label-indicator { - .bg_q; - border-radius: 50%; - display: inline-block; - height: 10px; - margin-right: 6px; - vertical-align: middle; - width: 10px; - - &.valid { - .bg_l; - } - - &.invalid { - .bg_h; - } - } - - // --------------------------------------------------------------------------------------------------- - // Leftbar - // --------------------------------------------------------------------------------------------------- - .w-sdc-designer-leftbar { - background-color: @main_color_p; - bottom: 0; - left: 0; - overflow-y: scroll; - overflow-x: hidden; - position: absolute; - top: 0; - width: 244px; - .box-shadow(7px -3px 6px -8px @main_color_n); - - } - - .w-sdc-designer-leftbar-title { - - .p_16_m; - background-color: @main_color_n; - line-height: 40px; - padding: 0 17px; - } - - .w-sdc-designer-leftbar-title-count { - float: right; - } - - .w-scd-diagram-container { - // left: 240px; - //right: 300px; - } - - .w-sdc-designer-leftbar-search { - background-color: @tlv_color_u; - padding: 10px; - white-space: nowrap; - position: relative; - } - - .w-sdc-designer-leftbar-search-input { - border: 1px solid @color_e; - .border-radius(4px); - height: 30px; - margin: 0; - padding: 0px 28px 3px 10px; - vertical-align: 4px; - width: 100%; - outline: none; - font-style: italic; - } - - .w-sdc-designer-leftbar-search-filter { - - } - - .i-sdc-designer-leftbar-section { - .hand; - } - - .i-sdc-designer-leftbar-section-title { - .m_14_m; - background-color: @tlv_color_u; - .hand; - clear: both; - height: 40px; - line-height: 40px; - margin-top: 1px; - padding: 0 10px; - position: relative; - text-transform: uppercase; - font-weight: bold; - } - - .i-sdc-designer-leftbar-section-title-icon { - .hand; - .sprite-new; - .arrow-up; - width: 15px; - height: 9px; - position: absolute; - right: 13px; - top: 18px; - transition: .3s all; - } - - .i-sdc-designer-leftbar-section.expanded .i-sdc-designer-leftbar-section-title-icon { - transform: rotate(180deg); - margin-right: 2px; - } - - .i-sdc-designer-leftbar-section-content { - background-color: @main_color_o; - } - - .i-sdc-designer-leftbar-section-content-item { - background-color: @main_color_p; - overflow: hidden; - - &:hover { - background-color: @main_color_p; - } - - .cp{ - margin: 6px; - } - - .vl{ - margin: 6px; - } - } - - .i-sdc-designer-leftbar-section-content-subcat { - .m_14_m; - background-color: @tlv_color_t; - line-height: 35px; - padding: 0 10px; - cursor: default; - - - &:hover { - background-color: @func_color_r; - } - - - } - - .i-sdc-designer-leftbar-section .i-sdc-designer-leftbar-section-content .i-sdc-designer-leftbar-section-content-item { - max-height: 0px; - margin: 0 auto; - transition: all .3s; - } - - .i-sdc-designer-leftbar-section.expanded .i-sdc-designer-leftbar-section-content .i-sdc-designer-leftbar-section-content-item { - max-height: 64px; - margin: 0 auto 1px auto; - // padding: 4px 13px; - } - - .i-sdc-designer-leftbar-section.expanded .i-sdc-designer-leftbar-section-content .i-sdc-designer-leftbar-section-content-subcat { - margin: 0; - } - - .i-sdc-designer-leftbar-section-content-item-icon-ph { - display: inline-block; - margin: 12px 0 12px 10px; - pointer-events: auto; - height: 45px; - width: 40px; - float: left; - display: flex; - align-items: center; - .non-certified { - position: relative; - left: -4px; - top: -4px; - .sprite; - .s-sdc-state-non-certified; - display: block; - - &.smaller-icon { - bottom: 6px; - left: 13px; - } - } - - - - } - - .non-certified { - position: relative; - left: 0px; - top: 0px; - .sprite; - .s-sdc-state-non-certified; - display: block; - - &.smaller-icon { - left: 35px; - bottom: -14px; - } - } - /* - .i-sdc-composition-leftbar-section-content-item-icon { - background-image: url('../../../styles/images/resource-icons/default.png'); - // position: absolute; - right: 20px; - top: 10px; - height: 40px; - width: 40px; - background-size: 40px; - } - */ - - .i-sdc-designer-leftbar-section-content-item-info { - display: inline-block; - // margin-left: 10px; - //overflow: hidden; - // vertical-align: middle; - width: 160px; - padding: 0 0 0 10px; - } - - .i-sdc-designer-leftbar-section-content-item-info-title { - .m_13_m; - line-height: 14px; - overflow: hidden; - text-overflow: ellipsis; - max-width: 120px; - display: inline-block; - white-space: nowrap; - vertical-align: bottom; - } - - .i-sdc-designer-leftbar-section-content-item-info-text { - .m_13_r; - line-height: 15px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - - .i-sdc-designer-leftbar-section-content-item-info-text-link { - color: @color_s; - text-decoration: underline; - float: right; - position: absolute; - right: 17px; - // bottom: 5px; - } - - // --------------------------------------------------------------------------------------------------- - // Form actions - // --------------------------------------------------------------------------------------------------- - .w-sdc-form-actions-container.add-property { - text-align: center; - width: 100%; - margin-top: 2px; - margin-bottom: 12px; - - .w-sdc-form-action { - width: 245px; - } - .w-sdc-form-action.add-property-add-another { - .bg_a; - margin-left: 35px; - } - .w-sdc-form-action.add-property-done { - margin-left: 312px; - } - .w-sdc-form-action.save { - margin-left: 327px; - margin-bottom: 30px; - } - - } - - // --------------------------------------------------------------------------------------------------- - // Top menu - // --------------------------------------------------------------------------------------------------- - .w-sdc-header-menu { - padding: 25px 0; - text-align: center; - white-space: nowrap; - } - - .i-sdc-header-menu-item { - cursor: pointer; - display: inline-block; - height: 43px; - min-width: 93px; - padding: 0 38px; - position: relative; - vertical-align: middle; - - &::after { - border-right: 1px solid @color_m; - content: ''; - display: block; - height: 43px; - right: 0; - position: absolute; - top: 0; - width: 2px; - } - - &:first-child { - &::before { - border-right: 1px solid @color_m; - content: ''; - display: block; - height: 43px; - left: 0; - position: absolute; - top: 0; - width: 2px; - } - } - } - - .i-sdc-header-menu-item-icon { - display: inline-block; - height: 20px; - width: 28px; - } - - .i-sdc-header-menu-item-label { - .g_1; - line-height: 18px; - } - - .service-path-buttons { - margin-top: 12px; - position: absolute; - right: 70px; - top: 53px; - &.with-sidebar { - right: 380px; - } - } - //Canvas search menu - .w-sdc-search-menu { - position:absolute; - right: 18px; - top:53px; - transition: right 0.2s; - display: flex; - flex-direction: column; - align-items: flex-end; - margin-right:10px; - pointer-events: none; - - & > * { - pointer-events: all; - } - - &.with-sidebar { - right:320px; - } - - .search-with-autocomplete-container.composition-search { - margin-top: 12px; - - .search-bar-input { - width: 250px; - padding:2px 50px 2px 10px; - transition:all 0.4s; - } - .search-bar-container { - position:relative; - } - - &:not(:hover):not(.autocomplete-visible):not(.active){ - border-radius: 0; - box-shadow:none; - - .search-bar-input:not(:focus){ - width: 0px; - padding:0; - border:none; - } - .clear-search-x { - display:none; - } - .search-bar-input:not(:focus) ~ .search-bar-button { - border-radius: 2px; - border:solid 1px #fff; - } - } - } - - .zoom-icons { - border:solid 1px #fff; - border-radius: 2px; - box-shadow: 0px 2px 3.88px 0.12px rgba(0, 0, 0, 0.29); - background-color: rgba(234, 234, 234, 0.88); - background-repeat: no-repeat; - margin-top: 10px; - - &:hover { - cursor:pointer; - } - - &:active { - border:none; - background-color: rgba(31, 171, 223, 0.88); - } - } - } - - // --------------------------------------------------------------------------------------------------- - // Canvas inline menu - // --------------------------------------------------------------------------------------------------- - .w-sdc-canvas-menu-list { - .w-sdc-canvas-menu-item-view { - &::before { - content: ''; - display: inline-block; - - .sprite-new; - .view-icon; - vertical-align: top; - margin: 2px 6px 2px 4px; - } - } - - .w-sdc-canvas-menu-item-delete { - &::before { - content: ''; - display: inline-block; - - .sprite-new; - .delete-icon; - vertical-align: bottom; - margin: 1px 10px 0 7px; - } - } - } -} -/*.right-tab-loader { - border: 16px solid #f3f3f3; !* Light grey *! - border-top: 16px solid #3498db; !* Blue *! - border-radius: 50%; - width: 120px; - height: 120px; - animation: spin 2s linear infinite; -}*/ - -@keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view-model.ts deleted file mode 100644 index 2af341b2c1..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view-model.ts +++ /dev/null @@ -1,352 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import * as _ from "lodash"; -import { - ArtifactModel, - Service, - IAppConfigurtaion, - Resource, - Component, - ComponentInstance, - ArtifactGroupModel, - IFileDownload -} from "app/models"; -import {ICompositionViewModelScope} from "../../composition-view-model"; -import {ArtifactsUtils, ModalsHandler, ArtifactGroupType} from "app/utils"; -import {GRAPH_EVENTS} from "app/utils/constants"; -import {EventListenerService} from "app/services/event-listener-service"; -import {Dictionary} from "../../../../../../utils/dictionary/dictionary"; - -export interface IArtifactsViewModelScope extends ICompositionViewModelScope { - artifacts:Array; - artifactType:string; - downloadFile:IFileDownload; - isLoading:boolean; - allowDeleteAndUpdateArtifactMap:Dictionary; - getTitle():string; - addOrUpdate(artifact:ArtifactModel):void; - delete(artifact:ArtifactModel):void; - download(artifact:ArtifactModel):void; - openEditEnvParametersModal(artifact:ArtifactModel):void; - getEnvArtifact(heatArtifact:ArtifactModel):any; - getEnvArtifactName(artifact:ArtifactModel):string; - isLicenseArtifact(artifact:ArtifactModel):boolean; - isVfOrPnf():boolean; - //isVFiArtifact(artifact:ArtifactModel):boolean; -} - -export class ResourceArtifactsViewModel { - - static '$inject' = [ - '$scope', - '$filter', - '$state', - 'sdcConfig', - 'ArtifactsUtils', - 'ModalsHandler', - '$q', - 'EventListenerService' - ]; - - constructor(private $scope:IArtifactsViewModelScope, - private $filter:ng.IFilterService, - private $state:any, - private sdcConfig:IAppConfigurtaion, - private artifactsUtils:ArtifactsUtils, - private ModalsHandler:ModalsHandler, - private $q:ng.IQService, - private eventListenerService: EventListenerService) { - - this.initScope(); - } - - - private initArtifactArr = (artifactType:string):void => { - let artifacts:Array = []; - - if (this.$scope.selectedComponent) { - if ('interface' == artifactType) { - let interfaces = this.$scope.currentComponent.interfaces; - if (interfaces && interfaces.standard && interfaces.standard.operations) { - - angular.forEach(interfaces.standard.operations, (operation:any, interfaceName:string):void => { - let item:ArtifactModel = {}; - if (operation.implementation) { - item = operation.implementation; - } - item.artifactDisplayName = interfaceName; - item.artifactLabel = interfaceName; - item.mandatory = false; - artifacts.push(item); - }); - } - } else { - //init normal artifacts, deployment or api artifacts - let artifactsObj:ArtifactGroupModel; - switch (artifactType) { - case "api": - artifactsObj = (this.$scope.currentComponent).serviceApiArtifacts; - break; - case "deployment": - if (!this.$scope.isComponentInstanceSelected()) { - artifactsObj = this.$scope.currentComponent.deploymentArtifacts; - } else { - artifactsObj = this.$scope.currentComponent.selectedInstance.deploymentArtifacts; - } - break; - default: - //artifactsObj = this.$scope.selectedComponent.artifacts; - if (!this.$scope.isComponentInstanceSelected()) { - artifactsObj = this.$scope.currentComponent.artifacts; - } else { - artifactsObj = this.$scope.currentComponent.selectedInstance.artifacts; - } - break; - } - _.forEach(artifactsObj, (artifact:ArtifactModel, key) => { - artifacts.push(artifact); - }); - } - } - this.$scope.artifacts = artifacts; - this.$scope.allowDeleteAndUpdateArtifactMap = new Dictionary(); - _.forEach(this.$scope.artifacts, (artifact:ArtifactModel)=>{ - this.$scope.allowDeleteAndUpdateArtifactMap[artifact.artifactLabel] = this.allowDeleteAndUpdateArtifact(artifact); - }); - this.$scope.isLoading = false; - this.$scope.preventMoveTab(false); - }; - - - private convertToArtifactUrl = (artifactType:string):string => { - - switch (artifactType) { - case 'deployment': - return 'DEPLOYMENT'; - case 'api': - return 'SERVICE_API'; - default: - return 'INFORMATIONAL'; - } - - } - - private loadComponentArtifactIfNeeded = (forceLoad?: boolean) => { - - let onGetComponentArtifactsSuccess = (artifacts:ArtifactGroupModel)=> { - switch (this.$scope.artifactType) { - case 'deployment': - this.$scope.currentComponent.deploymentArtifacts = artifacts; - break; - case 'api': - (this.$scope.currentComponent).serviceApiArtifacts = artifacts; - break; - default: - this.$scope.currentComponent.artifacts = artifacts; - break; - } - this.$scope.isLoading = false; - this.initArtifactArr(this.$scope.artifactType); - } - - let onError = ()=> { - this.$scope.isLoading = false; - }; - - switch (this.$scope.artifactType) { - case 'deployment': - if(forceLoad || !this.$scope.currentComponent.deploymentArtifacts) { - this.$scope.component.getArtifactByGroupType(this.convertToArtifactUrl(this.$scope.artifactType)).then(onGetComponentArtifactsSuccess, onError); - } else { - this.initArtifactArr(this.$scope.artifactType); - } - - break; - case 'api': - if(!(this.$scope.currentComponent).serviceApiArtifacts) { - this.$scope.component.getArtifactByGroupType(this.convertToArtifactUrl(this.$scope.artifactType)).then(onGetComponentArtifactsSuccess, onError); - } else { - this.initArtifactArr(this.$scope.artifactType); - } - break; - default: - if(!this.$scope.currentComponent.artifacts) { - this.$scope.component.getArtifactByGroupType(this.convertToArtifactUrl(this.$scope.artifactType)).then(onGetComponentArtifactsSuccess, onError); - } else { - this.initArtifactArr(this.$scope.artifactType); - } - break; - } - } - private loadArtifacts = (forceLoad?: boolean):void => { - - let onGetInstanceArtifactsSuccess = (artifacts:ArtifactGroupModel)=> { - switch (this.$scope.artifactType) { - case 'deployment': - this.$scope.currentComponent.selectedInstance.deploymentArtifacts = artifacts; - break; - default: - this.$scope.currentComponent.selectedInstance.artifacts = artifacts; - break; - } - this.initArtifactArr(this.$scope.artifactType); - }; - - let onError = ()=> { - this.$scope.isLoading = false; - }; - - this.$scope.isLoading = true; - this.$scope.preventMoveTab(true); - if (this.$scope.isComponentInstanceSelected()) { - this.$scope.component.getComponentInstanceArtifactsByGroupType(this.$scope.component.selectedInstance.uniqueId, this.convertToArtifactUrl(this.$scope.artifactType)).then(onGetInstanceArtifactsSuccess, onError); - } else { - this.loadComponentArtifactIfNeeded(forceLoad); - } - } - - private updateArtifactsIfNeeded = ():void => { - if (this.$scope.artifactType === "deployment") { - this.loadArtifacts(true); - } else { - this.initArtifactArr(this.$scope.artifactType); - } - }; - - private openEditArtifactModal = (artifact:ArtifactModel):void => { - this.ModalsHandler.openArtifactModal(artifact, this.$scope.currentComponent).then(():void => { - this.updateArtifactsIfNeeded(); - }); - }; - - private allowDeleteAndUpdateArtifact = (artifact:ArtifactModel):boolean => { - if(!this.$scope.isViewMode()){ - if(this.$scope.isComponentInstanceSelected()){//is artifact of instance - return !this.$scope.selectedComponent.deploymentArtifacts || !this.$scope.selectedComponent.deploymentArtifacts[artifact.artifactLabel];//if the artifact is not from instance parent - }else{//is artifact of main component - return (!artifact.isHEAT() && !artifact.isThirdParty() && !this.$scope.isLicenseArtifact(artifact)); - } - } - return false; -}; - - private initScope = ():void => { - - this.$scope.isLoading = false; - this.$scope.artifactType = this.artifactsUtils.getArtifactTypeByState(this.$state.current.name); - this.$scope.getTitle = ():string => { - return this.artifactsUtils.getTitle(this.$scope.artifactType, this.$scope.currentComponent); - }; - - // Bug 310499 - user should be unable to delete RI artifact. (also talked to David and agreed this function isn't necessary) - // this.$scope.isVFiArtifact = (artifact:ArtifactModel):boolean=> { - // if (artifact.artifactGroupType === ArtifactGroupType.INFORMATION) {//fix DE256847 - // return this.$scope.currentComponent.artifacts && (!this.$scope.currentComponent.artifacts[artifact.artifactLabel] || !this.$scope.currentComponent.artifacts[artifact.artifactLabel].artifactName); - // } - // return this.$scope.currentComponent.selectedInstance && this.$scope.currentComponent.selectedInstance.deploymentArtifacts && this.$scope.currentComponent.selectedInstance.deploymentArtifacts[artifact.artifactLabel]; - // }; - - this.$scope.addOrUpdate = (artifact:ArtifactModel):void => { - this.artifactsUtils.setArtifactType(artifact, this.$scope.artifactType); - let artifactCopy = new ArtifactModel(artifact); - this.openEditArtifactModal(artifactCopy); - }; - - - this.$scope.delete = (artifact:ArtifactModel):void => { - - let onOk = ():void => { - this.$scope.isLoading = true; - this.artifactsUtils.removeArtifact(artifact, this.$scope.artifacts); - - let success = (responseArtifact:ArtifactModel):void => { - this.initArtifactArr(this.$scope.artifactType); - this.$scope.isLoading = false; - }; - - let error = (error:any):void => { - console.log('Delete artifact returned error:', error); - this.initArtifactArr(this.$scope.artifactType); - this.$scope.isLoading = false; - }; - if (this.$scope.isComponentInstanceSelected()) { - this.$scope.currentComponent.deleteInstanceArtifact(artifact.uniqueId, artifact.artifactLabel).then(success, error); - } else { - this.$scope.currentComponent.deleteArtifact(artifact.uniqueId, artifact.artifactLabel).then(success, error);//TODO simulate error (make sure error returns) - } - }; - let title:string = this.$filter('translate')("ARTIFACT_VIEW_DELETE_MODAL_TITLE"); - let message:string = this.$filter('translate')("ARTIFACT_VIEW_DELETE_MODAL_TEXT", "{'name': '" + artifact.artifactDisplayName + "'}"); - this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk); - }; - - - this.$scope.getEnvArtifact = (heatArtifact:ArtifactModel):any=> { - return _.find(this.$scope.artifacts, (item:ArtifactModel)=> { - return item.generatedFromId === heatArtifact.uniqueId; - }); - }; - - this.$scope.getEnvArtifactName = (artifact:ArtifactModel):string => { - let envArtifact = this.$scope.getEnvArtifact(artifact); - if (envArtifact) { - return envArtifact.artifactDisplayName; - } - }; - - this.$scope.isLicenseArtifact = (artifact:ArtifactModel):boolean => { - let isLicense:boolean = false; - if (this.$scope.component.isResource() && (this.$scope.component).isCsarComponent()) { - isLicense = this.artifactsUtils.isLicenseType(artifact.artifactType); - } - - return isLicense; - }; - - this.$scope.openEditEnvParametersModal = (artifact:ArtifactModel):void => { - this.ModalsHandler.openEditEnvParametersModal(artifact, this.$scope.currentComponent).then(()=> { - this.updateArtifactsIfNeeded(); - }, ()=> { - // ERROR - }); - }; - - this.$scope.isVfOrPnf = ():boolean => { - if (this.$scope.selectedComponent.isResource()) { - let selectedResourceType = (this.$scope.selectedComponent).resourceType; - return selectedResourceType == 'VF' || selectedResourceType == 'PNF'; - } - return false; - } - - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_NODE_SELECTED, this.loadArtifacts); - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED, this.loadArtifacts); - - this.$scope.$on('$destroy', () => { - - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_NODE_SELECTED, this.loadArtifacts); - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED, this.loadArtifacts); - }); - - this.loadArtifacts(); - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view.html b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view.html deleted file mode 100644 index ec81ed81ee..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view.html +++ /dev/null @@ -1,84 +0,0 @@ - - - -
    - - - -
    -
    - -
    -
    -
    - -
    -
    -
    - -
    - - - -
    -
    - -
    - Description:{{artifact.description}} -
    -
    - - - - - - - - -
    -
    - -
    - -
    -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts.less b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts.less deleted file mode 100644 index 5256542788..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/artifacts/artifacts.less +++ /dev/null @@ -1,173 +0,0 @@ -.w-sdc-designer-sidebar-tab-content.artifacts { - - .i-sdc-designer-sidebar-section-content-item-artifact.hand { - .hand; - } - - .w-sdc-designer-sidebar-section-content { - padding: 0; - } - .w-sdc-designer-sidebar-section-title { - &.expanded { - margin-bottom: 0; - } - } - - .i-sdc-designer-sidebar-section-content-item-artifact-details { - display: inline-block; - margin-left: 5px; - vertical-align: middle; - width: 180px; - &.heat { - line-height: 18px; - width: 250px; - } - } - - .i-sdc-designer-sidebar-section-content-item-artifact-details-name { - .s_14_r; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-width:220px; - display: inline-block; - //text-transform: capitalize; - &.enabled { - &:hover { - .a_7; - font-family: @font-opensans-regular - } - } - - } - - .i-sdc-designer-sidebar-section-content-item-artifact-heat-env { - .g_7; - margin-top: 6px; - line-height: 42px; - padding-top: 10px; - border-top:1px solid #c8cdd1; - .enabled { - &:hover { - .hand; - .a_7; - } - } - } - - .i-sdc-designer-sidebar-section-content-item-artifact-filename { - .g_7; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-width: 225px; - display: inline-block; - .bold; - &.enabled { - &:hover { - .a_7; - } - } - } - - - .i-sdc-designer-sidebar-section-content-item-file-link{ - border-left: 1px #848586 solid; - height: 58px; - margin-left: -11px; - margin-top: 11px; - border-top: 1px #848586 solid; - border-bottom: 1px #848586 solid; - width: 12px; - float: left; - } - - .i-sdc-designer-sidebar-section-content-item-artifact-details-desc { - display: none; - line-height: 16px; - word-wrap: break-word; - white-space: normal; - } - - .i-sdc-designer-sidebar-section-content-item-artifact-details-desc-label { - .b_3; - } - - - .i-sdc-designer-sidebar-section-content-item-artifact { - border-bottom: 1px solid #c8cdd1; - padding: 5px 10px 5px 18px; - position: relative; - // line-height: 36px; - min-height: 61px; - //cursor: default; - display: flex; - align-items: center; - - - .i-sdc-designer-sidebar-section-content-item-button { - top: 20px; - line-height: 10px; - } - - &:hover { - //background-color: @color_c; - .bg_c; - transition: all .3s; - - .i-sdc-designer-sidebar-section-content-item-button { - display: block; - - } - - } - } - -} - -///////////////////Lifecycle Management -.i-sdc-designer-sidebar-section-content-item-lm { - .b_7; - border-bottom: 1px solid @color_e; - cursor: pointer; - height: 65px; - padding: 22px 0; - position: relative; - - &:hover { - .bg_c_hover; - margin-left: -10px; - margin-right: -10px; - padding: 22px 10px; - - .i-sdc-designer-sidebar-section-content-item-lm-icon { - right: 16px; - } - } -} - -.i-sdc-designer-sidebar-section-content-item-lm:first-child { - margin-top: -18px; -} - -.i-sdc-designer-sidebar-section-content-item-lm-icon { - position: absolute; - right: 6px; - - //TODO: Replace the icons. - &.icon-view { - background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAJCAYAAAACTR1pAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDE0IDc5LjE1Njc5NywgMjAxNC8wOC8yMC0wOTo1MzowMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjdGMDNBRUJDMDkxNjExRTVCMjRBOEI5QzMxQTlBQjY4IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjdGMDNBRUJEMDkxNjExRTVCMjRBOEI5QzMxQTlBQjY4Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6N0YwM0FFQkEwOTE2MTFFNUIyNEE4QjlDMzFBOUFCNjgiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6N0YwM0FFQkIwOTE2MTFFNUIyNEE4QjlDMzFBOUFCNjgiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4U2decAAABRUlEQVR42pyRPUvDUBSG39t2UyyaBgvWQZMqKoFq4lBH0U0UqXSxKPaPieCoWPAPKIgdjG1ohaghOrSR1iaLKMXpmnMhQVfPcLmc8zxwPhjnHFE4rx3eMO/w4rr4+vwQuZHRMcwqClaMVeRnplnEskg8O7/g96YJSZLgBz5+R0bKIAgC6IaBvdKukBP0HJ+cctu2cVCtQsrIUFUVlcp+LE6EItWIIVaIV9c3/PnRRqlcxkJeYV2vi+/hEO/9QSx6b56oEUMsOal6/TacQcXinCpaGE+n0QnljufFIuUoiAlZTk6iWFyD6zpoWi3RwvrmBlLJZCzRn3IUxBBLjlgO9e06T9ja3sGyrqPX66NtWQLWCgVks5Owmg1c1mpQ8vM4OqywP1s1w1PkpnJY0jTIsizy/sDHQ7sFmt0ITxJtlf33jj8CDADhB52tEX6ifAAAAABJRU5ErkJggg=='); - height: 9px; - top: 29px; - width: 14px; - } - - //TODO: Replace the icons. - &.icon-alert { - background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAANCAYAAAB2HjRBAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDE0IDc5LjE1Njc5NywgMjAxNC8wOC8yMC0wOTo1MzowMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjhBM0YxQTBCMDkyMDExRTVBNzlCQUYxNEYwMDUwOTQ5IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjhBM0YxQTBDMDkyMDExRTVBNzlCQUYxNEYwMDUwOTQ5Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OEEzRjFBMDkwOTIwMTFFNUE3OUJBRjE0RjAwNTA5NDkiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OEEzRjFBMEEwOTIwMTFFNUE3OUJBRjE0RjAwNTA5NDkiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7exgceAAAB5klEQVR42oySy2tTQRTGfzN3cpvbpFTaUlzUjeCuVFyJf4DuCl34wL/CrbpUunLnwpUuFFy48IFiwYWhpYuW+gCLrbWKBQumaRIba5ub3MccJ5WECCV44MDMme873/lmBhGhnZulcn/3/sfrO7J/45R017pT0xUS2bC93vy2LAOLt5DfCeUn14RD4h/ysbHRDii/8pyo7DmFiP7VZ4Rbu9KT3I7i+qJklp7ibQt2J6HeNOhXV/gv8tDcbaLtXYLJKeTcZfxqSPPzvGu6ID3J1Q8z0ny/hIkM5swF8qenUFUfwixHCtd7Kwez04jOgEmc+hq6tuZ8N9E6xG5U+Pn2kRxKLs7eE7tRc0XlToRM2sD+2sGmDiY+kWsSFG528Kr1Xgfjfn0n5uElvFrrzVqVDHqkiTKjxCsV9LBx08QkgcY/eZH+89Oqo+x9eumkwQaQaoPEKWpsHHN8ArItgLt5UdiG6736mFLxixyQt+bviik8QPuaNFRIkjqQRZ2YJDo6QWydjTRtOcGPPdJKgnlxFfN9fVmGNhecR4U3mLrL6nPTRTQHXZO5+4jyyI4Iqs99GJvgBiKjcySlj3897y6/kbreI4w0QS7ASxrsa4/cXkxkIzK5PKmNqRMw7NfdeczA+Fn1R4ABAPnMAeCjkgf5AAAAAElFTkSuQmCC'); - height: 13px; - top: 27px; - width: 15px; - } - -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details-view-model.ts deleted file mode 100644 index 36ceabfb42..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details-view-model.ts +++ /dev/null @@ -1,201 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import * as _ from "lodash"; -import {Component, ModalModel, ButtonModel} from "app/models"; -import {GRAPH_EVENTS} from "app/utils"; -import {LeftPaletteLoaderService, EventListenerService} from "app/services"; -import {ICompositionViewModelScope} from "../../composition-view-model"; -import {LeftPaletteComponent} from "../../../../../../models/components/displayComponent"; -import {ComponentServiceFactoryNg2} from "app/ng2/services/component-services/component.service.factory"; -import {ServiceServiceNg2} from 'app/ng2/services/component-services/service.service'; -import {Service} from "app/models/components/service"; -import {ModalService} from 'app/ng2/services/modal.service'; - -export interface IEditResourceVersion { - allVersions:any; - changeVersion:string; -} - -interface IDetailsViewModelScope extends ICompositionViewModelScope { - isLoading:boolean; - $parent:ICompositionViewModelScope; - expandedSection:Array; - editForm:ng.IFormController; - editResourceVersion:IEditResourceVersion; - - onChangeResourceVersion():void; - alertBeforeChangeResourceVersion():void; - changeVersion():void; - cancelChangeResourceVersion():void; -} - -export class DetailsViewModel { - - static '$inject' = [ - '$scope', - '$filter', - 'LeftPaletteLoaderService', - 'EventListenerService', - 'ComponentServiceFactoryNg2', - 'ServiceServiceNg2', - 'ModalServiceNg2' - ]; - - constructor(private $scope:IDetailsViewModelScope, - private $filter:ng.IFilterService, - private LeftPaletteLoaderService:LeftPaletteLoaderService, - private eventListenerService:EventListenerService, - private ComponentServiceFactoryNg2: ComponentServiceFactoryNg2, - private serviceService: ServiceServiceNg2, - private ModalServiceNg2: ModalService) { - this.initScope(); - } - - private clearSelectedVersion = ():void => { - this.$scope.editResourceVersion = { - allVersions: {}, - changeVersion: null - }; - }; - - private versioning:Function = (versionNumber:string):string => { - let version:Array = versionNumber.split('.'); - return '00000000'.slice(version[0].length) + version[0] + '.' + '00000000'.slice(version[1].length) + version[1]; - }; - - private initEditResourceVersion = ():void => { - this.clearSelectedVersion(); - this.$scope.editResourceVersion.allVersions[this.$scope.currentComponent.selectedInstance.componentVersion] = this.$scope.currentComponent.selectedInstance.componentUid; - _.merge(this.$scope.editResourceVersion.allVersions, angular.copy(this.$scope.selectedComponent.allVersions)); - let sorted:any = _.sortBy(_.toPairs(this.$scope.editResourceVersion.allVersions), (item)=> { - return this.versioning(item[0]); - }); - this.clearSelectedVersion(); - _.forEach(sorted, (item)=> { - this.$scope.editResourceVersion.allVersions[item[0]] = item[1]; - }); - - let highestVersion = _.last(Object.keys(this.$scope.selectedComponent.allVersions)); - - if (parseFloat(highestVersion) % 1) { //if highest is minor, make sure it is the latest checked in - - let latestVersionComponent:LeftPaletteComponent = _.maxBy(_.filter(this.LeftPaletteLoaderService.getLeftPanelComponentsForDisplay(this.$scope.currentComponent), (component:LeftPaletteComponent) => { //latest checked in - return (component.systemName === this.$scope.selectedComponent.systemName - || component.uuid === this.$scope.selectedComponent.uuid); - }),(component)=>{return component.version}); - - let latestVersion:string = latestVersionComponent ? latestVersionComponent.version : highestVersion; - - if (highestVersion != latestVersion) { //highest is checked out - remove from options - this.$scope.editResourceVersion.allVersions = _.omit(this.$scope.editResourceVersion.allVersions, highestVersion); - } - } - this.$scope.editResourceVersion.changeVersion = this.$scope.currentComponent.selectedInstance.componentVersion; - }; - - private initScope = ():void => { - this.$scope.isLoading = false; - this.$scope.$parent.isLoading = false; - this.$scope.expandedSection = ['general', 'tags']; - //this.clearSelectedVersion(); - - this.$scope.$watch('selectedComponent', (component:Component) => { - if (this.$scope.isComponentInstanceSelected()) { - this.initEditResourceVersion(); - } - }); - - this.$scope.onChangeResourceVersion = ():void => { - if(this.$scope.isComponentInstanceSelected() && this.$scope.currentComponent.selectedInstance.isServiceProxy()) { - this.$scope.alertBeforeChangeResourceVersion(); - } - else { - this.$scope.changeVersion(); - } - }; - - this.$scope.alertBeforeChangeResourceVersion = ():void => { - let modalApproveTxt:string = this.$filter('translate')("MODAL_APPROVE"); - let modalCancelTxt:string = this.$filter('translate')("MODAL_CANCEL"); - let changeVersionModalTitle:string = this.$filter('translate')("DETAILS_TAB_CHANGE_VERSION_MODAL_TITLE"); - let changeVersionModalMsg:string = this.$filter('translate')("DETAILS_TAB_CHANGE_VERSION_MODAL_MSG"); - - let actionButton: ButtonModel = new ButtonModel(modalApproveTxt, 'blue', this.$scope.changeVersion); - let cancelButton: ButtonModel = new ButtonModel(modalCancelTxt, 'grey', this.$scope.cancelChangeResourceVersion); - let modalModel: ModalModel = new ModalModel('sm', changeVersionModalTitle, changeVersionModalMsg, [actionButton, cancelButton]); - let customModal = this.ModalServiceNg2.createCustomModal(modalModel); - customModal.instance.open(); - }; - - this.$scope.cancelChangeResourceVersion = () => { - this.ModalServiceNg2.closeCurrentModal(); - this.$scope.editResourceVersion.changeVersion = this.$scope.currentComponent.selectedInstance.componentVersion; - }; - - this.$scope.changeVersion = ():void => { - this.ModalServiceNg2.closeCurrentModal(); - this.$scope.isLoading = true; - this.$scope.$parent.isLoading = true; - - let service = this.$scope.currentComponent; - let {changeVersion} = this.$scope.editResourceVersion; - let componentUid:string = this.$scope.editResourceVersion.allVersions[changeVersion]; - - let onCancel = (error:any) => { - this.$scope.isLoading = false; - this.$scope.$parent.isLoading = false; - this.$scope.editResourceVersion.changeVersion = this.$scope.currentComponent.selectedInstance.componentVersion; - - if (error) { - console.log(error); - } - }; - - let onUpdate = () => { - let onSuccess = (component:Component) => { - this.$scope.isLoading = false; - this.$scope.$parent.isLoading = false; - this.$scope.onComponentInstanceVersionChange(component); - }; - - this.$scope.currentComponent.changeComponentInstanceVersion(componentUid).then(onSuccess, onCancel); - }; - - if (this.$scope.currentComponent.isService()) { - this.serviceService.checkComponentInstanceVersionChange(service, componentUid).subscribe((pathsToDelete:string[]) => { - if (pathsToDelete && pathsToDelete.length) { - this.$scope.isLoading = false; - this.$scope.$parent.isLoading = false; - this.$scope.$parent.openVersionChangeModal(pathsToDelete).then(() => { - this.$scope.isLoading = true; - this.$scope.$parent.isLoading = true; - onUpdate(); - }, onCancel); - } else { - onUpdate(); - } - }, onCancel); - } else { - onUpdate(); - } - }; - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details-view.html b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details-view.html deleted file mode 100644 index db5322a859..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details-view.html +++ /dev/null @@ -1,181 +0,0 @@ - - - - -
    - - - - General Info -
    -
    - -
    -
    - Type: - -
    -
    - Resource Type: - -
    -
    - - Version: - - - - -
    -
    - Category: - -
    -
    - Sub Category: - -
    -
    - Creation Date: - -
    -
    - Author: - - -
    -
    - - -
    -
    - Vendor Name: - - -
    -
    - Vendor Release: - - -
    -
    - - - -
    -
    - - - -
    -
    - - - -
    -
    - - -
    - -
    - - -
    - -
    -
    -
    -
    -
    - Description: - - - -
    - -
    -
    - -
    - - Additional Information -
    -
    - -
    -
    - - : - -
    -
    -
    - - -
    - - Tags -
    -
    - -
    -
    - - -
    -
    -
    -
    - - - diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details.less b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details.less deleted file mode 100644 index 90bb5658c8..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/details/details.less +++ /dev/null @@ -1,81 +0,0 @@ -.w-sdc-designer-sidebar-tab-content.details { - - .w-sdc-designer-sidebar-section-title + .w-sdc-designer-sidebar-section-content { - padding: 0 10px 0 18px; - } - - .w-sdc-designer-sidebar-section-title.expanded + .w-sdc-designer-sidebar-section-content { - padding: 10px 10px 10px 18px; - } - - .i-sdc-designer-sidebar-section-content-item-label { - font-family: @font-opensans-medium; - color: #191919; - font-size: 13px; - &.additional-information{ - max-width:100px; - display: inline-block; - text-overflow: ellipsis; - overflow: hidden; - vertical-align: bottom; - } - - } - - - - .i-sdc-designer-sidebar-section-content-item-value { - // .hyphenate; - font-family: @font-opensans-regular; - color: #191919; - font-size: 13px; - padding-left: 10px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - //display: inline-block; fix long name for firefox - max-width: 160px; - vertical-align:bottom; - font-weight: normal; - &.vendor-model-number{ - max-width: 110px; - } - &.additional-information{ - max-width:160px; - display: inline-block; - } - &.i-sdc-form-select { - .b_1; - border: 1px solid @border_color_f; - width: 210px; - max-width: 210px; - padding-left: 4px; - - .select-instance-version { - .b_1; - &.minor { - .h_1; - } - } - } - &.minor { - .h_1; - } - } - .i-sdc-designer-sidebar-section-content-description-item-value{ - max-width: none; - font-weight: normal; - font-family: @font-opensans-regular; - } - - .customization-uuid{ - .f-type._12_m; - } - - .w-sdc-designer-sidebar-section.tags { - .i-sdc-designer-sidebar-section-content-item { - white-space: normal; - } - } - -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties-view-model.ts deleted file mode 100644 index e3ddecd9a5..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties-view-model.ts +++ /dev/null @@ -1,244 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import * as _ from "lodash"; -import { - AttributeModel, - AttributesGroup, - Component, - ComponentInstance, - PropertyModel, - PropertiesGroup -} from "app/models"; -import {ICompositionViewModelScope} from "../../composition-view-model"; -import {ModalsHandler} from "app/utils"; -import {ComponentServiceNg2} from "app/ng2/services/component-services/component.service"; -import {ComponentGenericResponse} from "app/ng2/services/responses/component-generic-response"; - -interface IResourcePropertiesAndAttributesViewModelScope extends ICompositionViewModelScope { - properties:PropertiesGroup; - attributes:AttributesGroup; - propertiesMessage:string; - groupPropertiesByInstance:boolean; - showGroupsOfInstanceProperties:Array; - addProperty():void; - updateProperty(property:PropertyModel):void; - deleteProperty(property:PropertyModel):void; - viewAttribute(attribute:AttributeModel):void; - groupNameByKey(key:string):string; - isPropertyOwner():boolean; - getComponentInstanceNameFromInstanceByKey(key:string):string; -} - -export class ResourcePropertiesViewModel { - - static '$inject' = [ - '$scope', - '$filter', - '$uibModal', - 'ModalsHandler', - 'ComponentServiceNg2' - - ]; - - - constructor(private $scope:IResourcePropertiesAndAttributesViewModelScope, - private $filter:ng.IFilterService, - private $uibModal:ng.ui.bootstrap.IModalService, - private ModalsHandler:ModalsHandler, - private ComponentServiceNg2:ComponentServiceNg2) { - - this.getComponentInstancesPropertiesAndAttributes(); - } - - private initComponentProperties = ():void => { - let result:PropertiesGroup = {}; - - if (this.$scope.selectedComponent) { - this.$scope.propertiesMessage = undefined; - this.$scope.groupPropertiesByInstance = false; - if (this.$scope.isComponentInstanceSelected()) { - if (this.$scope.currentComponent.selectedInstance.originType === 'VF') { - this.$scope.groupPropertiesByInstance = true; - } - result[this.$scope.currentComponent.selectedInstance.uniqueId] = this.$scope.currentComponent.componentInstancesProperties[this.$scope.currentComponent.selectedInstance.uniqueId]; - } else if (this.$scope.currentComponent.isService()) { - // Temporally fix to hide properties for service (UI stack when there are many properties) - result = this.$scope.currentComponent.componentInstancesProperties; - this.$scope.propertiesMessage = "Note: properties for service are disabled"; - } else { - let key = this.$scope.selectedComponent.uniqueId; - result[key] = Array(); - let derived = Array(); - _.forEach(this.$scope.selectedComponent.properties, (property:PropertyModel) => { - if (key == property.parentUniqueId) { - result[key].push(property); - } else { - property.readonly = true; - derived.push(property); - } - }); - if (derived.length) { - result['derived'] = derived; - } - } - this.$scope.properties = result; - } - }; - - - private initComponentAttributes = ():void => { - let result:AttributesGroup = {}; - - if (this.$scope.selectedComponent) { - if (this.$scope.isComponentInstanceSelected()) { - result[this.$scope.currentComponent.selectedInstance.uniqueId] = this.$scope.currentComponent.componentInstancesAttributes[this.$scope.currentComponent.selectedInstance.uniqueId]; - } else if (this.$scope.currentComponent.isService()) { - result = this.$scope.currentComponent.componentInstancesAttributes; - } - this.$scope.attributes = result; - } - }; - - /** - * This function is checking if the component is the value owner of the current property - * in order to notify the edit property modal which fields to disable - */ - private isPropertyValueOwner = ():boolean => { - return this.$scope.currentComponent.isService() || !!this.$scope.currentComponent.selectedInstance; - }; - - /** - * The function opens the edit property modal. - * It checks if the property is from the VF or from one of it's resource instances and sends the needed property list. - * For create property reasons an empty array is transferd - * - * @param property the wanted property to edit/create - */ - private openEditPropertyModal = (property:PropertyModel):void => { - this.ModalsHandler.openEditPropertyModal(property, - this.$scope.component, - (this.$scope.isPropertyOwner() ? - this.$scope.properties[property.parentUniqueId] : - this.$scope.properties[property.resourceInstanceUniqueId]) || [], - this.isPropertyValueOwner(), "component", property.resourceInstanceUniqueId).then((updatedProperty:PropertyModel) => { - if(updatedProperty){ - let oldProp = _.find(this.$scope.properties[updatedProperty.resourceInstanceUniqueId], (prop:PropertyModel) => {return prop.uniqueId == updatedProperty.uniqueId;}); - oldProp.value = updatedProperty.value; - } - }); - }; - - private openAttributeModal = (atrribute:AttributeModel):void => { - - let modalOptions:ng.ui.bootstrap.IModalSettings = { - template: 'app/view-models/forms/attribute-form/attribute-form-view.html', - controller: 'Sdc.ViewModels.AttributeFormViewModel', - size: 'sdc-md', - backdrop: 'static', - keyboard: false, - resolve: { - attribute: ():AttributeModel => { - return atrribute; - }, - component: ():Component => { - return this.$scope.currentComponent; - } - } - }; - this.$uibModal.open(modalOptions); - }; - - private getComponentInstancesPropertiesAndAttributes = () => { - - this.ComponentServiceNg2.getComponentInstanceAttributesAndProperties(this.$scope.currentComponent).subscribe((genericResponse:ComponentGenericResponse) => { - this.$scope.currentComponent.componentInstancesAttributes = genericResponse.componentInstancesAttributes; - this.$scope.currentComponent.componentInstancesProperties = genericResponse.componentInstancesProperties; - this.initScope(); - }); - }; - - private initScope = ():void => { - - - this.initComponentProperties(); - this.initComponentAttributes(); - - this.$scope.$watchCollection('currentComponent.properties', (newData:any):void => { - this.initComponentProperties(); - }); - - this.$scope.$watch('currentComponent.selectedInstance', (newInstance:ComponentInstance):void => { - if (angular.isDefined(newInstance)) { - this.initComponentProperties(); - this.initComponentAttributes(); - - } - }); - - this.$scope.isPropertyOwner = ():boolean => { - return this.$scope.currentComponent && this.$scope.currentComponent.isResource() && !this.$scope.isComponentInstanceSelected(); - }; - - this.$scope.updateProperty = (property:PropertyModel):void => { - this.openEditPropertyModal(property); - }; - - this.$scope.deleteProperty = (property:PropertyModel):void => { - - let onOk = ():void => { - this.$scope.currentComponent.deleteProperty(property.uniqueId); - }; - - let title:string = this.$filter('translate')("PROPERTY_VIEW_DELETE_MODAL_TITLE"); - let message:string = this.$filter('translate')("PROPERTY_VIEW_DELETE_MODAL_TEXT", "{'name': '" + property.name + "'}"); - this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk); - }; - - this.$scope.viewAttribute = (attribute:AttributeModel):void => { - this.openAttributeModal(attribute); - }; - - this.$scope.groupNameByKey = (key:string):string => { - switch (key) { - case 'derived': - return "Derived"; - - case this.$scope.currentComponent.uniqueId: - return this.$filter("resourceName")(this.$scope.currentComponent.name); - - default: - let componentInstance = _.find(this.$scope.currentComponent.componentInstances, {uniqueId: key}); - if(componentInstance) - return this.$filter("resourceName")(componentInstance.name); - } - }; - - this.$scope.getComponentInstanceNameFromInstanceByKey = (key:string):string => { - let instanceName:string = ""; - if (key !== undefined && this.$scope.selectedComponent.uniqueId == this.$scope.currentComponent.selectedInstance.componentUid) { - instanceName = this.$filter("resourceName")((_.find(this.$scope.selectedComponent.componentInstances, {uniqueId: key})).name); - } - return instanceName; - }; - - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties-view.html b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties-view.html deleted file mode 100644 index cdd69682dc..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties-view.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - -
    - - - - -
    -
    - -
    -
    - -
    -
    -
    -
    - {{property.name}} -
    -
    - {{property.defaultValue}} - {{property.value}} -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - {{instanceProperty.name}} -
    -
    - - {{instanceProperty.value === undefined ? instanceProperty.defaultValue : instanceProperty.value}} -
    -
    -
    -
    -
    - - - - - -
    - - - - -
    -
    - -
    -
    - -
    -
    -
    -
    - {{attribute.name}} -
    -
    - {{attribute.defaultValue}} - {{attribute.value}} -
    -
    -
    - -
    - -
    -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties.less b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties.less deleted file mode 100644 index ce5acc83e5..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties.less +++ /dev/null @@ -1,39 +0,0 @@ -.w-sdc-designer-sidebar-tab-content.properties { - .i-sdc-designer-sidebar-section-content-item-property-and-attribute-label{ - display:block; - font-weight: bold; - } - .i-sdc-designer-sidebar-section-content-item-button.update{ - right: 17px; - } - .i-sdc-designer-sidebar-section-content-item-button.delete{ - right: 35px; - } - - .w-sdc-designer-sidebar-properties-disabled { - .s_14_m; - padding: 20px 20px; - } - - .vfci-properties-group{ - background-color: @func_color_r; - } - - .expand-collapse-title-icon{ - .hand; - .sprite-new; - .expand-collapse-plus-icon; - vertical-align: middle; - margin: 0 6px; - } - - .expanded { - .expand-collapse-title-icon { - .expand-collapse-minus-icon; - } - } - - .w-sdc-designer-sidebar-section-title-text{ - vertical-align: middle; - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/relations/relations-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/relations/relations-view-model.ts deleted file mode 100644 index ce44aaff50..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/relations/relations-view-model.ts +++ /dev/null @@ -1,177 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import * as _ from "lodash"; -import {ICompositionViewModelScope} from "../../composition-view-model"; -import {CapabilitiesGroup, Requirement, RequirementsGroup} from "app/models"; -import {ComponentServiceNg2} from "app/ng2/services/component-services/component.service"; -import {ComponentGenericResponse} from "app/ng2/services/responses/component-generic-response"; -import {GRAPH_EVENTS} from "app/utils"; -import {EventListenerService} from "app/services"; -import {ComponentInstance, Capability} from "app/models"; - -interface IRelationsViewModelScope extends ICompositionViewModelScope { - isLoading:boolean; - $parent:ICompositionViewModelScope; - getRelation(requirement:any):any; - capabilities:Array; - requirements:Array; - - //for complex components - capabilitiesInstancesMap:InstanceCapabilitiesMap; - requirementsInstancesMap:InstanceRequirementsMap; -} -export class InstanceCapabilitiesMap { - [key:string]:Array; -} - -export class InstanceRequirementsMap { - [key:string]:Array; -} - -export class RelationsViewModel { - - static '$inject' = [ - '$scope', - '$filter', - 'ComponentServiceNg2', - 'EventListenerService' - ]; - - constructor(private $scope:IRelationsViewModelScope, - private $filter:ng.IFilterService, - private ComponentServiceNg2:ComponentServiceNg2, - private eventListenerService:EventListenerService) { - this.initScope(); - } - - private loadComplexComponentData = () => { - this.$scope.isLoading = true; - this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.$scope.currentComponent.componentType, this.$scope.currentComponent.uniqueId).subscribe((response:ComponentGenericResponse) => { - this.$scope.currentComponent.capabilities = response.capabilities; - this.$scope.currentComponent.requirements = response.requirements; - this.setScopeCapabilitiesRequirements(this.$scope.currentComponent.capabilities, this.$scope.currentComponent.requirements); - this.initInstancesMap(); - this.$scope.isLoading = false; - }); - } - - - private extractValuesFromMap = (map:CapabilitiesGroup | RequirementsGroup):Array => { - let values = []; - _.forEach(map, (capabilitiesOrRequirements:Array | Array, key) => { - values = values.concat(capabilitiesOrRequirements) - } - ); - return values; - } - - private setScopeCapabilitiesRequirements = (capabilities:CapabilitiesGroup, requirements:RequirementsGroup) => { - this.$scope.capabilities = this.extractValuesFromMap(capabilities); - this.$scope.requirements = this.extractValuesFromMap(requirements); - } - - - private initInstancesMap = ():void => { - - this.$scope.capabilitiesInstancesMap = new InstanceCapabilitiesMap(); - _.forEach(this.$scope.capabilities, (capability:Capability) => { - if (this.$scope.capabilitiesInstancesMap[capability.ownerName]) { - this.$scope.capabilitiesInstancesMap[capability.ownerName] = this.$scope.capabilitiesInstancesMap[capability.ownerName].concat(capability); - } else { - this.$scope.capabilitiesInstancesMap[capability.ownerName] = new Array(capability); - } - }); - - this.$scope.requirementsInstancesMap = new InstanceRequirementsMap(); - _.forEach(this.$scope.requirements, (requirement:Requirement) => { - if (this.$scope.requirementsInstancesMap[requirement.ownerName]) { - this.$scope.requirementsInstancesMap[requirement.ownerName] = this.$scope.requirementsInstancesMap[requirement.ownerName].concat(requirement); - } else { - this.$scope.requirementsInstancesMap[requirement.ownerName] = new Array(requirement); - } - }); - } - - private initRequirementsAndCapabilities = (needUpdate?: boolean) => { - - // if instance selected, we take the requirement and capabilities of the instance - always exist because we load them with the graph - if (this.$scope.isComponentInstanceSelected()) { - this.$scope.isLoading = false; - this.setScopeCapabilitiesRequirements(this.$scope.currentComponent.selectedInstance.capabilities, this.$scope.currentComponent.selectedInstance.requirements); - if (this.$scope.currentComponent.selectedInstance.originType === 'VF') { - this.initInstancesMap(); - } - } else { - // if instance not selected, we take the requirement and capabilities of the VF/SERVICE, if not exist we call api - if (needUpdate || !this.$scope.currentComponent.capabilities || !this.$scope.currentComponent.requirements) { - this.loadComplexComponentData(); - - } else { - this.$scope.isLoading = false; - this.setScopeCapabilitiesRequirements(this.$scope.currentComponent.capabilities, this.$scope.currentComponent.requirements); - this.initInstancesMap(); - } - } - } - - private updateRequirementCapabilities = () => { - if (!this.$scope.isComponentInstanceSelected()) { - this.loadComplexComponentData(); - } - } - - private initEvents = ():void => { - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_NODE_SELECTED, this.initRequirementsAndCapabilities); - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED, this.updateRequirementCapabilities); - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_CREATE_COMPONENT_INSTANCE, this.updateRequirementCapabilities); - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_DELETE_COMPONENT_INSTANCE, this.updateRequirementCapabilities); - } - - private initScope = ():void => { - - this.$scope.requirements = []; - this.$scope.capabilities = []; - - this.initEvents(); - this.initRequirementsAndCapabilities(); - - this.$scope.isCurrentDisplayComponentIsComplex = ():boolean => { - if (this.$scope.isComponentInstanceSelected()) { - if (this.$scope.currentComponent.selectedInstance.originType === 'VF') { - return true; - } - return false; - } else { - return this.$scope.currentComponent.isComplex(); - } - } - - this.$scope.$on('$destroy', () => { - - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_NODE_SELECTED, this.initRequirementsAndCapabilities); - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED, this.updateRequirementCapabilities); - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_CREATE_COMPONENT_INSTANCE, this.updateRequirementCapabilities); - this.eventListenerService.unRegisterObserver(GRAPH_EVENTS.ON_DELETE_COMPONENT_INSTANCE, this.updateRequirementCapabilities); - }); - - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/relations/relations-view.html b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/relations/relations-view.html deleted file mode 100644 index 889f129dac..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/relations/relations-view.html +++ /dev/null @@ -1,77 +0,0 @@ - - - -
    -
    - Capabilities -
    -
    -
    - -
    -
    -
    - Requirements -
    -
    - -
    - -
    -
    -
    - -
    -
    - Capabilities -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    - -
    -
    - -
    - Requirements -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    - -
    -
    -
    -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/relations/relations.less b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/relations/relations.less deleted file mode 100644 index c3b224d5a6..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/relations/relations.less +++ /dev/null @@ -1,14 +0,0 @@ -.w-sdc-designer-sidebar-tab-content.relations { - - .w-sdc-designer-sidebar-section-content { - padding: 0; - } - - .w-sdc-designer-sidebar-section-title { - &.expanded { - margin-bottom: 0; - } - } -} - - diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/service-consumption/service-consumption-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/service-consumption/service-consumption-view-model.ts deleted file mode 100644 index 737002303b..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/service-consumption/service-consumption-view-model.ts +++ /dev/null @@ -1,101 +0,0 @@ -/*! -* Copyright © 2016-2018 European Support Limited -* -* 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. -*/ - - -import {ICompositionViewModelScope} from "../../composition-view-model"; -import { - Service, - PropertiesGroup, - InputsGroup, - ServiceInstanceObject, - InterfaceModel, - InputBEModel, - CapabilitiesGroup, - Capability, - ComponentInstance -} from 'app/models'; -import {ComponentGenericResponse} from "app/ng2/services/responses/component-generic-response"; -import {ServiceServiceNg2} from "app/ng2/services/component-services/service.service"; - -interface IServiceConsumptionViewModelScope extends ICompositionViewModelScope { - service: Service; - instancesMappedList: Array; - componentInstancesProperties: PropertiesGroup; - componentInstancesInputs: InputsGroup; - componentInstancesInterfaces: Map>; - componentInputs: Array; - componentCapabilities: Array; - instancesCapabilitiesMap: Map>; -} - - -export class ServiceConsumptionViewModel { - - static '$inject' = [ - '$scope', - 'ServiceServiceNg2' - ]; - - constructor(private $scope:IServiceConsumptionViewModelScope, private ServiceServiceNg2:ServiceServiceNg2) { - this.$scope.service = this.$scope.currentComponent; - this.initInstances(); - this.initScope(); - } - - private initInstances = ():void => { - this.ServiceServiceNg2.getServiceConsumptionData(this.$scope.service).subscribe((genericResponse:ComponentGenericResponse) => { - this.$scope.componentInstancesProperties = genericResponse.componentInstancesProperties; - this.$scope.componentInstancesInputs = genericResponse.componentInstancesInputs; - this.$scope.componentInstancesInterfaces = genericResponse.componentInstancesInterfaces; - this.$scope.componentInputs = genericResponse.inputs; - this.buildInstancesCapabilitiesMap(genericResponse.componentInstances); - this.updateInstanceAttributes(); - }); - } - - buildInstancesCapabilitiesMap = (componentInstances: Array): void => { - this.$scope.instancesCapabilitiesMap = new Map(); - let flattenCapabilities = []; - _.forEach(componentInstances, componentInstance => { - flattenCapabilities = CapabilitiesGroup.getFlattenedCapabilities(componentInstance.capabilities); - this.$scope.instancesCapabilitiesMap[componentInstance.uniqueId] = _.filter(flattenCapabilities, cap => cap.properties && cap.ownerId === componentInstance.uniqueId); - }); - } - - private updateInstanceAttributes = ():void => { - if (this.$scope.isComponentInstanceSelected() && this.$scope.componentInstancesProperties) { - this.$scope.instancesMappedList = this.$scope.service.componentInstances.map(coInstance => new ServiceInstanceObject({ - id: coInstance.uniqueId, - name: coInstance.name, - properties: this.$scope.componentInstancesProperties[coInstance.uniqueId] || [], - inputs: this.$scope.componentInstancesInputs[coInstance.uniqueId] || [], - interfaces: this.$scope.componentInstancesInterfaces[coInstance.uniqueId] || [] - })); - } - } - - private initScope = ():void => { - this.$scope.$watch('currentComponent.selectedInstance', ():void => { - this.updateInstanceAttributes(); - }); - - this.$scope.registerCreateInstanceEvent(() => { - this.initInstances(); - }); - - this.$scope.$on('$destroy', this.$scope.unregisterCreateInstanceEvent); - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/service-consumption/service-consumption-view.html b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/service-consumption/service-consumption-view.html deleted file mode 100644 index 8404a7f653..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/service-consumption/service-consumption-view.html +++ /dev/null @@ -1,23 +0,0 @@ - -
    - - Operation Consumption -
    -
    - -
    -
    - - -
    -
    -
    -
    \ No newline at end of file diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/service-dependencies/service-dependencies-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/service-dependencies/service-dependencies-view-model.ts deleted file mode 100644 index b634e6021f..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/service-dependencies/service-dependencies-view-model.ts +++ /dev/null @@ -1,125 +0,0 @@ -/*! - * Copyright © 2016-2018 European Support Limited - * - * 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. - */ - - -import {ICompositionViewModelScope} from "../../composition-view-model"; -import {Service, ComponentInstance, PropertiesGroup, ServiceInstanceObject, PropertyBEModel} from 'app/models'; -import {ComponentServiceNg2} from "app/ng2/services/component-services/component.service"; -import {ConstraintObject} from "app/ng2/components/logic/service-dependencies/service-dependencies.component"; -import {ComponentGenericResponse} from 'app/ng2/services/responses/component-generic-response'; -import {DEPENDENCY_EVENTS} from "app/utils/constants"; -import {EventListenerService} from 'app/services'; - -interface IServiceDependenciesViewModelScope extends ICompositionViewModelScope { - service: Service; - selectedInstanceSiblings: Array; - componentInstancesConstraints: Array; - selectedInstanceConstraints: Array; - selectedInstanceProperties: Array; - updateSelectedInstanceConstraints(constraintsList:Array): void; - loadConstraints(): void; - componentInstanceProperties: PropertiesGroup; - notifyDependencyEventsObserver: Function; -} - - - -export class ServiceDependenciesViewModel { - - static '$inject' = [ - '$scope', - 'ComponentServiceNg2', - 'EventListenerService' - ]; - - constructor(private $scope:IServiceDependenciesViewModelScope, private ComponentServiceNg2:ComponentServiceNg2, private eventListenerService: EventListenerService) { - this.$scope.service = this.$scope.currentComponent; - this.$scope.notifyDependencyEventsObserver = this.notifyDependencyEventsObserver; - this.initInstancesWithProperties(); - this.loadConstraints(); - - this.initScope(); - } - - private initInstancesWithProperties = ():void => { - this.ComponentServiceNg2.getComponentInstanceProperties(this.$scope.currentComponent).subscribe((genericResponse:ComponentGenericResponse) => { - this.$scope.componentInstanceProperties = genericResponse.componentInstancesProperties; - this.updateInstanceAttributes(); - }); - } - - private updateInstanceAttributes = ():void => { - if (this.$scope.isComponentInstanceSelected() && this.$scope.componentInstanceProperties) { - let instancesMappedList = this.$scope.service.componentInstances.map(coInstance => new ServiceInstanceObject({ - id: coInstance.uniqueId, - name: coInstance.name, - properties: this.$scope.componentInstanceProperties[coInstance.uniqueId] || [] - })); - this.$scope.selectedInstanceProperties = this.$scope.componentInstanceProperties[this.$scope.currentComponent.selectedInstance.uniqueId]; - this.$scope.selectedInstanceSiblings = instancesMappedList.filter(coInstance => coInstance.id !== this.$scope.currentComponent.selectedInstance.uniqueId); - } - } - - private initScope = ():void => { - this.$scope.$watch('currentComponent.selectedInstance', (newInstance:ComponentInstance):void => { - if (angular.isDefined(newInstance) && this.$scope.componentInstancesConstraints) { - this.updateInstanceAttributes(); - this.$scope.selectedInstanceConstraints = this.$scope.componentInstancesConstraints[this.$scope.currentComponent.selectedInstance.uniqueId] ? - this.$scope.componentInstancesConstraints[this.$scope.currentComponent.selectedInstance.uniqueId].properties : - []; - } - }); - this.$scope.$watch('componentInstancesConstraints', (constraints: Array):void => { - if (angular.isDefined(constraints)) { - if(this.$scope.isComponentInstanceSelected()) { - this.$scope.selectedInstanceConstraints = this.$scope.componentInstancesConstraints[this.$scope.currentComponent.selectedInstance.uniqueId] ? - this.$scope.componentInstancesConstraints[this.$scope.currentComponent.selectedInstance.uniqueId].properties || [] : - []; - } - } - }); - - this.$scope.updateSelectedInstanceConstraints = (constraintsList:Array):void => { - this.$scope.componentInstancesConstraints[this.$scope.currentComponent.selectedInstance.uniqueId].properties = constraintsList; - this.$scope.selectedInstanceConstraints = this.$scope.componentInstancesConstraints[this.$scope.currentComponent.selectedInstance.uniqueId].properties; - } - - this.$scope.loadConstraints = ():void => { - this.loadConstraints(); - } - - this.$scope.registerCreateInstanceEvent(() => { - this.initInstancesWithProperties(); - }); - - this.$scope.registerChangeComponentInstanceNameEvent((updatedComponentInstance) => { - this.$scope.currentComponent.selectedInstance = updatedComponentInstance; - }); - - this.$scope.$on('$destroy', this.$scope.unregisterCreateInstanceEvent); - this.$scope.$on('$destroy', this.$scope.unregisterChangeComponentInstanceNameEvent); - } - - private loadConstraints = ():void => { - this.ComponentServiceNg2.getServiceFilterConstraints(this.$scope.service).subscribe((response) => { - this.$scope.componentInstancesConstraints = response.nodeFilterData; - }); - } - - public notifyDependencyEventsObserver = (isChecked: boolean):void => { - this.eventListenerService.notifyObservers(DEPENDENCY_EVENTS.ON_DEPENDENCY_CHANGE, isChecked); - } -} \ No newline at end of file diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/service-dependencies/service-dependencies-view.html b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/service-dependencies/service-dependencies-view.html deleted file mode 100644 index ba50994529..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/service-dependencies/service-dependencies-view.html +++ /dev/null @@ -1,25 +0,0 @@ - - -
    - - Service Dependencies -
    -
    -
    -
    - - -
    -
    -
    -
    \ No newline at end of file diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/structure/structure-view.html b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/structure/structure-view.html deleted file mode 100644 index 4d89625e67..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/structure/structure-view.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - -
    - - Composition -
    -
    - -
    - -
    -
    -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/structure/structure-view.ts b/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/structure/structure-view.ts deleted file mode 100644 index 41f24dc8e8..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/structure/structure-view.ts +++ /dev/null @@ -1,34 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {ICompositionViewModelScope} from "../../composition-view-model"; - -interface IStructureViewModel extends ICompositionViewModelScope { -} - -export class StructureViewModel { - static '$inject' = [ - '$scope' - ]; - - constructor(private $scope:IStructureViewModel) { - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts-description-popover.html b/catalog-ui/src/app/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts-description-popover.html deleted file mode 100644 index 94c28a0796..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts-description-popover.html +++ /dev/null @@ -1,39 +0,0 @@ - - - -
    - -
    - - -
    - - - -
    -
    -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts-view-model.ts deleted file mode 100644 index fc3de6e9e1..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts-view-model.ts +++ /dev/null @@ -1,352 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2019 Nokia. 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========================================================= - */ - -//@require "./*.html" -'use strict'; -import * as _ from "lodash"; -import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model"; -import {ArtifactModel, ArtifactGroupModel, Resource} from "app/models"; -import {ArtifactsUtils, ModalsHandler, ValidationUtils} from "app/utils"; -import {ComponentServiceNg2} from "app/ng2/services/component-services/component.service"; -import {ComponentGenericResponse} from "../../../../ng2/services/responses/component-generic-response"; -import {GenericArtifactBrowserComponent} from "../../../../ng2/components/logic/generic-artifact-browser/generic-artifact-browser.component"; -import {PathsAndNamesDefinition} from "../../../../models/paths-and-names"; -import {ModalService as ModalServiceSdcUI} from "sdc-ui/lib/angular/modals/modal.service"; -import {IModalConfig} from "sdc-ui/lib/angular/modals/models/modal-config"; -import {CacheService} from "../../../../services/cache-service"; -import {GabConfig} from "../../../../models/gab-config"; - -interface IDeploymentArtifactsViewModelScope extends IWorkspaceViewModelScope { - tableHeadersList:Array; - reverse:boolean; - sortBy:string; - artifacts:Array; - editForm:ng.IFormController; - isLoading:boolean; - artifactDescriptions:any; - selectedArtifactId:string; - popoverTemplate:string; - - addOrUpdate(artifact:ArtifactModel):void; - updateSelectedArtifact():void; - delete(artifact:ArtifactModel):void; - sort(sortBy:string):void; - noArtifactsToShow():boolean; - getValidationPattern(validationType:string, parameterType?:string):RegExp; - validateJson(json:string):boolean; - resetValue(parameter:any):void; - viewModeOrCsarComponent():boolean; - isLicenseArtifact(artifact:ArtifactModel):void; - getEnvArtifact(heatArtifact:ArtifactModel):ArtifactModel; - getEnvArtifactName(artifact:ArtifactModel):string; - openEditEnvParametersModal(artifact:ArtifactModel):void; - openDescriptionPopover(artifactId:string):void; - closeDescriptionPopover():void; -} - -export class DeploymentArtifactsViewModel { - - static '$inject' = [ - '$scope', - '$templateCache', - '$filter', - 'Sdc.Services.CacheService', - 'ValidationUtils', - 'ArtifactsUtils', - 'ModalsHandler', - 'ComponentServiceNg2', - 'ModalServiceSdcUI' - ]; - - constructor(private $scope:IDeploymentArtifactsViewModelScope, - private $templateCache:ng.ITemplateCacheService, - private $filter:ng.IFilterService, - private cacheService:CacheService, - private validationUtils:ValidationUtils, - private artifactsUtils:ArtifactsUtils, - private ModalsHandler:ModalsHandler, - private ComponentServiceNg2: ComponentServiceNg2, - private ModalServiceSdcUI: ModalServiceSdcUI) { - this.initScope(); - } - - private initDescriptions = ():void => { - this.$scope.artifactDescriptions = {}; - _.forEach(this.$scope.component.deploymentArtifacts, (artifact:ArtifactModel):void => { - this.$scope.artifactDescriptions[artifact.artifactLabel] = artifact.description; - }); - }; - - private setArtifact = (artifact:ArtifactModel):void => { - if (!artifact.description || !this.$scope.getValidationPattern('string').test(artifact.description)) { - artifact.description = this.$scope.artifactDescriptions[artifact.artifactLabel]; - } - }; - - private initScopeArtifacts = ()=> { - this.$scope.artifacts = _.values(this.$scope.component.deploymentArtifacts); - _.forEach(this.$scope.artifacts, (artifact:ArtifactModel):void => { - artifact.envArtifact = this.getEnvArtifact(artifact); - }); - }; - - private initArtifacts = (loadFromServer:boolean):void => { - if (loadFromServer) { - this.$scope.isLoading = true; - this.ComponentServiceNg2.getComponentDeploymentArtifacts(this.$scope.component).subscribe((response:ComponentGenericResponse) => { - this.$scope.component.deploymentArtifacts = response.deploymentArtifacts; - this.initScopeArtifacts(); - this.$scope.isLoading = false; - }); - } else { - this.initScopeArtifacts(); - } - - }; - - private getEnvArtifact = (heatArtifact:ArtifactModel):ArtifactModel=> { - return _.find(this.$scope.artifacts, (item:ArtifactModel)=> { - return item.generatedFromId === heatArtifact.uniqueId; - }); - }; - - private getCurrentArtifact = ():ArtifactModel => { - if (!this.$scope.selectedArtifactId) { - return null; - } - let artifact:ArtifactModel = this.$scope.artifacts.filter((art) => { - return art.uniqueId == this.$scope.selectedArtifactId; - })[0]; - return artifact; - } - - private initScope = ():void => { - let self = this; - this.$scope.isLoading = false; - this.$scope.selectedArtifactId = null; - this.initDescriptions(); - if(this.$scope.component.deploymentArtifacts) { - this.initArtifacts(false); - } else { - this.initArtifacts(true); - } - this.$scope.setValidState(true); - - this.$scope.tableHeadersList = [ - {title: 'Name', property: 'artifactDisplayName'}, - {title: 'Type', property: 'artifactType'}, - {title: 'Deployment timeout', property: 'timeout'}, - {title: 'Version', property: 'artifactVersion'}, - {title: 'UUID', property: 'artifactUUID'} - ]; - - this.$templateCache.put("deployment-artifacts-description-popover.html", require('app/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts-description-popover.html')); - this.$scope.popoverTemplate = "deployment-artifacts-description-popover.html"; - - this.$scope.isLicenseArtifact = (artifact:ArtifactModel):boolean => { - let isLicense:boolean = false; - if (this.$scope.component.isResource() && (this.$scope.component).isCsarComponent()) { - - isLicense = this.artifactsUtils.isLicenseType(artifact.artifactType); - } - - return isLicense; - }; - - this.$scope.sort = (sortBy:string):void => { - this.$scope.reverse = (this.$scope.sortBy === sortBy) ? !this.$scope.reverse : false; - this.$scope.sortBy = sortBy; - }; - - this.$scope.getValidationPattern = (validationType:string, parameterType?:string):RegExp => { - return this.validationUtils.getValidationPattern(validationType, parameterType); - }; - - this.$scope.validateJson = (json:string):boolean => { - if (!json) { - return true; - } - return this.validationUtils.validateJson(json); - }; - - this.$scope.viewModeOrCsarComponent = ():boolean => { - return this.$scope.isViewMode() || (this.$scope.component.isResource() && (this.$scope.component).isCsarComponent()); - }; - - this.$scope.addOrUpdate = (artifact:ArtifactModel):void => { - artifact.artifactGroupType = 'DEPLOYMENT'; - let artifactCopy = new ArtifactModel(artifact); - - let success = (response:any):void => { - this.$scope.artifactDescriptions[artifactCopy.artifactLabel] = artifactCopy.description; - this.initArtifacts(true); - // this.$scope.artifacts = _.values(this.$scope.component.deploymentArtifacts); - }; - - let error = (err:any):void => { - console.log(err); - this.initArtifacts(true); - // self.$scope.artifacts = _.values(self.$scope.component.deploymentArtifacts); - }; - - this.ModalsHandler.openArtifactModal(artifactCopy, this.$scope.component).then(success, error); - }; - - this.$scope.noArtifactsToShow = ():boolean => { - return !_.some(this.$scope.artifacts, 'esId'); - }; - - this.$scope.resetValue = (parameter:any):void => { - if (!parameter.currentValue && parameter.defaultValue) { - parameter.currentValue = parameter.defaultValue; - } - else if ('boolean' == parameter.type) { - parameter.currentValue = parameter.currentValue.toUpperCase(); - } - }; - - this.$scope.$watch('editForm.$valid', ():void => { - if (this.$scope.editForm) { - // this.$scope.setValidState(this.$scope.editForm.$valid); - } - }); - - this.$scope.updateSelectedArtifact = ():void => { - if (!this.$scope.isViewMode() && !this.$scope.isLoading) { - let artifact:ArtifactModel = this.getCurrentArtifact(); - this.setArtifact(artifact); //resets artifact description to original value if invalid. - if (artifact && artifact.originalDescription != artifact.description) { - this.$scope.isLoading = true; - let onSuccess = (responseArtifact:ArtifactModel):void => { - this.$scope.artifactDescriptions[responseArtifact.artifactLabel] = responseArtifact.description; - // this.$scope.artifacts = _.values(this.$scope.component.deploymentArtifacts); - this.initArtifacts(true); - this.$scope.isLoading = false; - }; - - let onFailed = (error:any):void => { - console.log('Delete artifact returned error:', error); - this.$scope.isLoading = false; - }; - - this.$scope.component.addOrUpdateArtifact(artifact).then(onSuccess, onFailed); - } - } - }; - - this.$scope.delete = (artifact:ArtifactModel):void => { - let onOk = ():void => { - this.$scope.isLoading = true; - let onSuccess = ():void => { - this.$scope.isLoading = false; - this.initArtifacts(true); - //this.$scope.artifacts = _.values(this.$scope.component.deploymentArtifacts); - }; - - let onFailed = (error:any):void => { - this.$scope.isLoading = false; - console.log('Delete artifact returned error:', error); - }; - - this.$scope.component.deleteArtifact(artifact.uniqueId, artifact.artifactLabel).then(onSuccess, onFailed); - }; - - let title:string = self.$filter('translate')("ARTIFACT_VIEW_DELETE_MODAL_TITLE"); - let message:string = self.$filter('translate')("ARTIFACT_VIEW_DELETE_MODAL_TEXT", "{'name': '" + artifact.artifactDisplayName + "'}"); - this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk); - }; - - this.$scope.getEnvArtifactName = (artifact:ArtifactModel):string => { - let envArtifact = this.$scope.getEnvArtifact(artifact); - if (envArtifact) { - return envArtifact.artifactDisplayName; - } - }; - - this.$scope.openGenericArtifactBrowserModal = (artifact:ArtifactModel):void => { - let self = this; - const title = 'Generic Artifact Browser'; - let modalConfig: IModalConfig = { - size: 'xl', - title: title, - type: 'custom', - buttons: [{ - id: 'closeGABButton', - text: 'Close', - size: "'x-small'", - closeModal: true - }] - }; - - const uiConfiguration: any = this.cacheService.get('UIConfiguration'); - let noConfig: boolean = false; - let pathsandnames: PathsAndNamesDefinition[] = []; - - if(typeof uiConfiguration.gab === 'undefined') { - noConfig = true; - } else { - const gabConfig: GabConfig = uiConfiguration.gab - .find(config => config.artifactType === artifact.artifactType); - if(typeof gabConfig === 'undefined') { - noConfig = true; - } else { - pathsandnames = gabConfig.pathsAndNamesDefinitions; - } - } - - if(noConfig) { - const msg = self.$filter('translate')("DEPLOYMENT_ARTIFACT_GAB_NO_CONFIG"); - this.ModalServiceSdcUI.openAlertModal(title, msg); - } - - const modalInputs = { - pathsandnames: pathsandnames, - artifactid: artifact.esId, - resourceid: this.$scope.component.uniqueId - }; - - this.ModalServiceSdcUI.openCustomModal(modalConfig, GenericArtifactBrowserComponent, modalInputs); - }; - - this.$scope.openEditEnvParametersModal = (artifact:ArtifactModel):void => { - this.ModalsHandler.openEditEnvParametersModal(artifact, this.$scope.component).then(()=> { - this.initArtifacts(true); - }, ()=> { - this.initArtifacts(true); - }); - }; - - this.$scope.openDescriptionPopover = (artifactId:string):void => { - if (this.$scope.selectedArtifactId && this.$scope.selectedArtifactId != artifactId) { - this.$scope.updateSelectedArtifact(); - } - this.$scope.selectedArtifactId = artifactId; - - }; - - this.$scope.closeDescriptionPopover = ():void => { - if (this.$scope.selectedArtifactId) { - this.$scope.updateSelectedArtifact(); - this.$scope.selectedArtifactId = null; - } - }; - }; -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts-view.html b/catalog-ui/src/app/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts-view.html deleted file mode 100644 index a26bcdeccd..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts-view.html +++ /dev/null @@ -1,147 +0,0 @@ - - -
    - -
    Add
    - -
    - -
    - -
    -
    {{header.title}} - -
    -
    -
    - -
    - - - - -
    -
    -
    -
    - -
    - {{artifact.artifactDisplayName}} - - -
    - -
    - {{artifact.artifactType}} -
    -
    - {{artifact.timeout? artifact.timeout:''}} -
    -
    - {{artifact.artifactVersion}} -
    -
    - {{artifact.artifactUUID}} -
    - -
    - - - - - -
    -
    -
    - -
    - {{artifact.envArtifact.artifactDisplayName}} -
    - -
    - {{artifact.envArtifact.artifactType}} -
    -
    - {{artifact.envArtifact.timeout? artifact.envArtifact.timeout:''}} -
    -
    - {{artifact.envArtifact.artifactVersion}} -
    -
    - {{artifact.envArtifact.artifactUUID}} -
    - - -
    - - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts.less b/catalog-ui/src/app/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts.less deleted file mode 100644 index f67d088b5a..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts.less +++ /dev/null @@ -1,201 +0,0 @@ -.workspace-deployment-artifact { - width: 93%; - display: inline-block; - .table-container-flex .table .body .data-row + div.item-opened { - align-items: center; - padding: 10px 40px 10px 30px; - } - - .w-sdc-classic-btn { - float: right; - margin-bottom: 10px; - } - - - .heat-env-connect-container{ - background-color: white; - position: absolute; - height: 70px; - width:20px; - left: 0; - top:0; - } - .heat-env-connect-container-view-mode{ - background-color: @tlv_color_t; - } - .heat-env-connect{ - border-left: 1px #848586 solid; - height: 50px; - margin-left: 10px; - margin-top: 10px; - border-top: 1px #848586 solid; - border-bottom: 1px #848586 solid; - width: 11px; - float: left; - - } - - .artifact-name{ - width:85%; - } - - .table-container-flex .table .body .data-row div .heat-env-connect-container{ - border-right: none; - } - - .i-sdc-designer-sidebar-section-content-item-file-link::before{ - content:""; - background-color: white; - width: 12px; - - } - - - - .table { - height:490px; - margin-bottom: 0; - } - - .parameter-description { - .circle(18px, @color_p); - content: '?'; - line-height: 18px; - vertical-align: middle; - margin-left: 5px; - cursor: default; - display: inline-block; - position: absolute; - top: 16px; - } - - .table-container-flex { - - margin-top: 0; - - .text{ - overflow: hidden; - text-overflow: ellipsis; - display: inline-block; - white-space: nowrap; - } - - .flex-item:nth-child(1) { - flex-grow: 15; - .hand; - padding-left: 30px; - position: relative; - span.table-arrow { - margin-right: 7px; - } - .description-popover-icon{ - float:right; - margin-top:6px; - } - } - - .flex-item:nth-child(2) { - flex-grow: 6; - } - - .flex-item:nth-child(3) { - flex-grow: 9; - } - - .flex-item:nth-child(4) { - flex-grow: 3; - } - - .flex-item:nth-child(5) { - flex-grow: 20; - } - - .flex-item:nth-child(6) { - flex-grow: 5; - - &.table-btn-col { - display: flex; - justify-content: space-between; - align-items: center; - - button { - flex: 0 1 auto; - background-color: transparent; - border: 0; - margin: 0; - } - .edit-paramtes-button { - order: -1; - } - } - } - } - .w-sdc-form{ - text-align: left; - - .w-sdc-env-params{ - border-top: 1px solid #cdcdcd; - margin: 25px 0 10px 0; - } - - .i-sdc-form-textarea { - border: 1px solid @color_e; - min-height: 60px; - padding: 10px 13px; - width: 100%; - resize: none; - - } - - .w-sdc-form-item { - &.error { - .i-sdc-form-input, - .i-sdc-form-select, - .i-sdc-form-textarea { - border-color: @color_h; - outline: none; - box-sizing: border-box; - } - } - } - - .i-sdc-env-form-label{ - font-family: @font-opensans-medium; - color: @main_color_m; - overflow: hidden; - max-width: 450px; - text-overflow: ellipsis; - display: inline-block; - white-space: nowrap; - margin-top: 14px; - - &.required::before { - color: #f33; - content: '*'; - margin-right: 4px; - } - } - } -} - -.table-container-flex .table .body .scrollbar-container { - overflow-x:auto !important; //need to override the overflow-hidden for the table so that the popover auto positioning works - min-height: 400px; -} - -.parameter-description-popover.deployment-artifact-view { - margin-left: -22px; - z-index: 1040; - min-width: 300px; - .input-error { - .q_12_m; - } - .error textarea{ - border-color: @main_color_g; - color: @color_h; - outline: none; - } - .popover-content textarea { - width:100%; - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment-view-model.ts deleted file mode 100644 index 9df377c5fc..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment-view-model.ts +++ /dev/null @@ -1,146 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model"; -import {ComponentFactory, MenuHandler, ChangeLifecycleStateHandler, ModalsHandler} from "app/utils"; -import {LeftPaletteLoaderService, CacheService, SharingService} from "app/services"; -import {Component, IAppMenu, Tab, ComponentInstance} from "app/models"; -import {GRAPH_EVENTS} from "../../../../utils/constants"; -import {ComponentGenericResponse} from "../../../../ng2/services/responses/component-generic-response"; -import {EventListenerService} from "../../../../services/event-listener-service"; -import {ComponentServiceNg2} from "../../../../ng2/services/component-services/component.service"; - -export interface IDeploymentViewModelScope extends IWorkspaceViewModelScope { - - currentComponent:Component; - selectedComponent:Component; - isLoading:boolean; - sharingService:SharingService; - sdcMenu:IAppMenu; - version:string; - isViewOnly:boolean; - tabs:Array; - selectedTab: Tab; - isComponentInstanceSelected():boolean; - updateSelectedComponent():void - openUpdateModal(); - deleteSelectedComponentInstance():void; - onBackgroundClick():void; - setSelectedInstance(componentInstance:ComponentInstance):void; - printScreen():void; - -} - -export class DeploymentViewModel { - - static '$inject' = [ - '$scope', - '$templateCache', - 'sdcMenu', - 'MenuHandler', - '$state', - 'Sdc.Services.SharingService', - '$filter', - 'Sdc.Services.CacheService', - 'ComponentFactory', - 'ChangeLifecycleStateHandler', - 'LeftPaletteLoaderService', - 'ModalsHandler', - 'EventListenerService', - 'ComponentServiceNg2' - ]; - - constructor(private $scope:IDeploymentViewModelScope, - private $templateCache:ng.ITemplateCacheService, - private sdcMenu:IAppMenu, - private MenuHandler:MenuHandler, - private $state:ng.ui.IStateService, - private sharingService:SharingService, - private $filter:ng.IFilterService, - private cacheService:CacheService, - private ComponentFactory:ComponentFactory, - private ChangeLifecycleStateHandler:ChangeLifecycleStateHandler, - private LeftPaletteLoaderService:LeftPaletteLoaderService, - private ModalsHandler:ModalsHandler, - private eventListenerService: EventListenerService, - private ComponentServiceNg2: ComponentServiceNg2) { - - this.$scope.setValidState(true); - this.initScope(); - this.initGraphData(); - } - - - private initComponent = ():void => { - - this.$scope.currentComponent = this.$scope.component; - this.$scope.selectedComponent = this.$scope.currentComponent; - this.updateUuidMap(); - this.$scope.isViewOnly = this.$scope.isViewMode(); - }; - - - private updateUuidMap = ():void => { - /** - * In case user press F5, the page is refreshed and this.sharingService.currentEntity will be undefined, - * but after loadService or loadResource this.sharingService.currentEntity will be defined. - * Need to update the uuidMap with the new resource or service. - */ - this.sharingService.addUuidValue(this.$scope.currentComponent.uniqueId, this.$scope.currentComponent.uuid); - }; - - private initRightTabs = ()=> { - if (this.$scope.currentComponent.modules) { - this.$templateCache.put("hierarchy-view.html", require('app/view-models/tabs/hierarchy/hierarchy-view.html')); - let hierarchyTab = new Tab("hierarchy-view.html", 'Sdc.ViewModels.HierarchyViewModel', 'hierarchy', this.$scope.isViewMode(), this.$scope.currentComponent, 'hierarchy'); - this.$scope.tabs.push(hierarchyTab) - } - } - - private initGraphData = ():void => { - if(!this.$scope.component.componentInstances || !this.$scope.component.componentInstancesRelations || !this.$scope.component.modules) { - this.ComponentServiceNg2.getDeploymentGraphData(this.$scope.component).subscribe((response:ComponentGenericResponse) => { - this.$scope.component.componentInstances = response.componentInstances; - this.$scope.component.componentInstancesRelations = response.componentInstancesRelations; - this.$scope.component.modules = response.modules; - this.$scope.isLoading = false; - this.initComponent(); - this.initRightTabs(); - this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_DEPLOYMENT_GRAPH_DATA_LOADED); - this.$scope.selectedTab = this.$scope.tabs[0]; - }); - } else { - this.$scope.isLoading = false; - this.initRightTabs(); - this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_DEPLOYMENT_GRAPH_DATA_LOADED); - - } - }; - - private initScope = ():void => { - this.$scope.isLoading = true; - this.$scope.sharingService = this.sharingService; - this.$scope.sdcMenu = this.sdcMenu; - this.$scope.version = this.cacheService.get('version'); - this.initComponent(); - this.$scope.tabs = Array(); - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment-view.html b/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment-view.html deleted file mode 100644 index aae03135a3..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment-view.html +++ /dev/null @@ -1,26 +0,0 @@ - - -
    - -
    - -
    - -
    - -
    -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment.less b/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment.less deleted file mode 100644 index f51ff6220d..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/deployment/deployment.less +++ /dev/null @@ -1,34 +0,0 @@ -.deployment-view { - - display: inline-block; - text-align: left; - align-items: left; - padding: 0; - width: 100%; - height: 100%; - - .w-sdc-deployment-canvas { - .noselect; - .bg_c; - position: relative; - bottom: 0; - width: 100%; - height: 100%; - z-index: 0; - - .view-mode{ - background-color: #f8f8f8; - border:0; - } - } - - .w-sdc-deployment-right-bar { - - .noselect; - bottom: 0; - position: absolute; - right: 0px; - transition: right 0.2s; - top: @action_nav_height; - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal-view-model.ts deleted file mode 100644 index eab06f28e8..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal-view-model.ts +++ /dev/null @@ -1,104 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import * as _ from "lodash"; -import {Distribution, DistributionComponent, ExportExcel} from "app/models"; - -interface IDistributionStatusModalViewModelScope { - distribution:Distribution; - status:string; - getStatusCount(distributionComponent:Array):any; - getUrlName(url:string):string; - modalDitributionStatus:ng.ui.bootstrap.IModalServiceInstance; - footerButtons:Array; - //exportExcelData:ExportExcel; - close():void; - initDataForExportExcel():ExportExcel; -} - -export class DistributionStatusModalViewModel { - - static '$inject' = ['$scope', '$uibModalInstance', 'data', '$filter']; - - constructor(private $scope:IDistributionStatusModalViewModelScope, - private $uibModalInstance:ng.ui.bootstrap.IModalServiceInstance, - private data:any, - private $filter:ng.IFilterService) { - this.initScope(); - } - - private generateMetaDataForExportExcel = ():Array=> { - let metaData = []; - metaData[0] = 'Name:' + this.data.component.name + '| UUID:' + this.data.component.uuid + '| Invariant UUID:' + this.data.component.invariantUUID; - metaData[1] = 'Distribution ID:' + this.$scope.distribution.distributionID + - '| USER ID:' + this.$scope.distribution.userId + - '| Time[UTC]:' + this.$filter('date')(this.$scope.distribution.timestamp, 'MM/dd/yyyy h:mma', 'UTC') + - '| Status:' + this.$scope.distribution.deployementStatus; - return metaData; - }; - - private generateDataObjectForExportExcel = ():any=> { - let correctFormatDataObj = []; - _.each(this.$scope.distribution.distributionComponents, (dComponent:DistributionComponent) => { - if (dComponent.status == this.$scope.status) { - correctFormatDataObj.push({ - 'omfComponentID': dComponent.omfComponentID, - 'artiFactName': this.$scope.getUrlName(dComponent.url), - 'url': dComponent.url, - 'timestamp': this.$filter('date')(dComponent.timestamp, 'MM/dd/yyyy h:mma', 'UTC'), - 'status': dComponent.status - }); - } - }); - return correctFormatDataObj; - }; - - private initScope = ():void => { - this.$scope.distribution = this.data.distribution; - this.$scope.status = this.data.status; - this.$scope.modalDitributionStatus = this.$uibModalInstance; - - - this.$scope.getUrlName = (url:string):string => { - let urlName:string = _.last(url.split('/')); - return urlName; - }; - - this.$scope.initDataForExportExcel = ():ExportExcel => { - let exportExcelData = new ExportExcel(); - exportExcelData.fileName = this.$scope.status; - exportExcelData.groupByField = "omfComponentID"; - exportExcelData.tableHeaders = ["Component ID", "Artifact Name", "URL", "Time(UTC)", "Status"]; - exportExcelData.metaData = this.generateMetaDataForExportExcel(); - exportExcelData.dataObj = this.generateDataObjectForExportExcel(); - return exportExcelData; - }; - - this.$scope.close = ():void => { - this.$uibModalInstance.close(); - }; - - this.$scope.footerButtons = [ - {'name': 'Close', 'css': 'blue', 'callback': this.$scope.close} - ]; - - }; -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal-view.html b/catalog-ui/src/app/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal-view.html deleted file mode 100644 index 0e58959e9a..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal-view.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - -
    -
    - -
    - -
    - - -
    - - -
    -
      -
    • -
      - -
      -
      -
      -
      Distribution ID
      -
      -
      -
      -
      -
      -
      -
      -
      Time[UTC]:
      -
      -
      -
      - - -
      -
      -
      -
      Status: {{status}}
      - -
      -
      -
      - -
        -
      • -
        -
        -
        -
        {{omfComponentID}} {{omfComponentList.length}} -
        -
        -
        -
        -
        -
        -
        -
        Component ID
        -
        Artifact Name
        -
        URL
        -
        Time(UTC)
        -
        Status
        -
        - -
        -
        -
        - {{urlList[0].omfComponentID}} -
        -
        - {{getUrlName(urlList[0].url)}} -
        -
        -
        {{urlList[0].url}}
        - -
        -
        -
        -
        {{urlList[0].status}}
        -
        - - -
        -
        -
          -
        • - - {{distributionComponent.status}} - Reason: Component has determined artifact is not needed. - Reason: {{distributionComponent.errorReason}} -
        • -
        -
        -
        -
        -
        -
        -
      • -
      -
    • -
    -
    - -
    -
    - - -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal.less b/catalog-ui/src/app/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal.less deleted file mode 100644 index d167083a2b..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal.less +++ /dev/null @@ -1,40 +0,0 @@ -.w-sdc-classic-top-line-modal { - - .w-sdc-modal-head { - // border-bottom: none; - } - .w-sdc-distribution-view { - .actions-buttons { - height: 29px; - padding: 0 25px 0 0px; - span{ - float: right; - } - } - - .w-sdc-distribution-view-content { - height: 500px; - } - - .w-sdc-distribution-view-content-section { - - .w-sdc-distribute-parent-block { - .w-sdc-distribute-components-block { - - .omf-component-row { - .w-sdc-distribute-status-block { - margin-left: 0; - } - - } - div { - padding-left: 0; - } - } - - } - - } - } -} - diff --git a/catalog-ui/src/app/view-models/workspace/tabs/distribution/distribution-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/distribution/distribution-view-model.ts deleted file mode 100644 index 47ec1fd9e3..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/distribution/distribution-view-model.ts +++ /dev/null @@ -1,131 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import * as _ from "lodash"; -import {Distribution, DistributionComponent, Service} from "app/models"; -import {ModalsHandler, Dictionary} from "app/utils"; -import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model"; - -interface IDistributionViewModel extends IWorkspaceViewModelScope { - modalDistribution:ng.ui.bootstrap.IModalServiceInstance; - service:Service; - distributions:Array; - showComponents(distribution:Distribution):void; - markAsDeployed(distribution:Distribution):void; - getStatusCount(distributionComponent:Array):any; - initDistributions():void; - getUrlName(url:string):string; - close():void; - openDisributionStatusModal:Function; -} - -export class DistributionViewModel { - - static '$inject' = [ - '$scope', - 'ModalsHandler' - - ]; - - constructor(private $scope:IDistributionViewModel, - private ModalsHandler:ModalsHandler) { - this.initScope(); - this.$scope.setValidState(true); - } - - private initScope = ():void => { - this.$scope.service = this.$scope.component; - - - // Open Distribution status modal - this.$scope.openDisributionStatusModal = (distribution:Distribution, status:string):void => { - this.ModalsHandler.openDistributionStatusModal(distribution, status, this.$scope.component).then(()=> { - // OK - }, ()=> { - // ERROR - }); - }; - - - this.$scope.showComponents = (distribution:Distribution):void => { - let onError = (response) => { - console.info('onError showComponents', response); - }; - let onSuccess = (distributionComponents:Array) => { - distribution.distributionComponents = distributionComponents; - distribution.statusCount = this.$scope.getStatusCount(distribution.distributionComponents); - // distribution.components = this.aggregateDistributionComponent(distributionComponents);; - }; - this.$scope.service.getDistributionsComponent(distribution.distributionID).then(onSuccess, onError); - }; - - this.$scope.getStatusCount = (distributionComponent:Array):any => { - return _.countBy(distributionComponent, 'status') - }; - - this.$scope.getUrlName = (url:string):string => { - let urlName:string = _.last(url.split('/')); - return urlName; - }; - - this.$scope.markAsDeployed = (distribution:Distribution):void => { - let onError = (response) => { - console.info('onError markAsDeployed', response); - }; - let onSuccess = (result:any) => { - distribution.deployementStatus = 'Deployed'; - }; - this.$scope.service.markAsDeployed(distribution.distributionID).then(onSuccess, onError); - - }; - - this.$scope.initDistributions = ():void => { - let onError = (response) => { - console.info('onError initDistributions', response); - }; - let onSuccess = (distributions:Array) => { - this.$scope.distributions = distributions; - }; - this.$scope.service.getDistributionsList().then(onSuccess, onError); - }; - - this.$scope.initDistributions(); - - }; - - - private aggregateDistributionComponent = (distributionComponents:Array):any => { - let aggregateDistributions:Dictionary>> = new Dictionary>>(); - let tempAggregateDistributions:any = _.groupBy(distributionComponents, 'omfComponentID'); - let aa = new Dictionary>(); - - let tempAggregate:any; - _.forEach(tempAggregateDistributions, (distributionComponents:Array, omfComponentID:string)=> { - - let urls:any = _.groupBy(distributionComponents, 'url'); - aggregateDistributions.setValue(omfComponentID, urls); - // aggregateDistributions[omfComponentID] = ; - - }); - console.log(aggregateDistributions); - return aggregateDistributions; - }; -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/distribution/distribution-view.html b/catalog-ui/src/app/view-models/workspace/tabs/distribution/distribution-view.html deleted file mode 100644 index babe5c2e5a..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/distribution/distribution-view.html +++ /dev/null @@ -1,198 +0,0 @@ - - -
    -
    -
    DISTRIBUTION
    -
    - -
    -
    - - - -
    -
      -
    • -
      -
      -
      -
      -
      -
      Distribution ID
      -
      -
      -
      -
      -
      -
      -
      -
      Time[UTC]:
      -
      -
      -
      - - -
      -
      -
      -
      -
      -
      -
      Total Artifacts:
      -
      Notified:
      - - - - - -
      Deploy Errors:
      -
      Download Errors:
      -
      -
      -
      - -
        - -
      • -
        -
        -
        -
        {{omfComponentID}} {{(statusCount.NOT_NOTIFIED || 0) + (statusCount.NOTIFIED || 0) }} -
        -
        Notified:
        -
        Downloaded:
        -
        Deployed:
        -
        Not Notified:
        -
        Deploy Errors:
        -
        Download Errors:
        -
        -
        -
        -
        -
        -
        -
        Component ID
        -
        Artifact Name
        -
        URL
        -
        Time(UTC)
        -
        Status
        -
        - -
        -
        -
        - {{urlList[0].omfComponentID}} -
        -
        - {{urlList[0].displayUrl}} -
        -
        -
        {{urlList[0].url}}
        - -
        -
        -
        -
        - {{urlList[0].status}} -
        -
        - - -
        -
        -
          -
        • - - {{distributionComponent.status}} - Reason: Component has determined artifact is not needed. - Reason: {{distributionComponent.errorReason}} -
        • -
        -
        -
        -
        -
        -
        -
      • -
      -
    • -
    -
    - -
    -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/distribution/distribution.less b/catalog-ui/src/app/view-models/workspace/tabs/distribution/distribution.less deleted file mode 100644 index ee1f7ed2d6..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/distribution/distribution.less +++ /dev/null @@ -1,362 +0,0 @@ - -.w-sdc-distribution-view { - text-align: left; - - .g_1; - min-height: 500px; - - .w-sdc-distribution-view-distributed-green-text { - .l_9; - .bold; - } - .w-sdc-distribution-view-distributed-error-red-text { - .h_9; - .bold; - } - - .bg_c; - vertical-align: top; - padding: 30px 10px; - width: 100%; - - .w-sdc-distribution-view-header { - display: flex; - -webkit-justify-content: space-between; - margin: 0 25px 5px 40px; - - .header-spacer { - flex-grow: 5; - } - } - - .top-search { - position: relative; - input { - &.search-text { - height: 26px; - line-height: 26px; - margin: 0 18px 4px 20px; - padding-right: 25px; - } - - } - .magnification { - top: 8px; - right: 25px; - } - } - - .w-sdc-distribution-view-content { - .perfect-scrollbar; - padding: 0 25px 0 0px; - margin-bottom: 25px; - height: 700px; - overflow: hidden; - position: relative; - - } - - .w-sdc-distribution-view-title { - .s_14_r; - - line-height: 30px; - - span { - padding-left: 5px; - } - } - - .blue-font { - .a_14_m; - - } - - .red-font { - .q_14_m; - } - - .w-sdc-distribution-view-block { - div { - display: inline-block; - } - } - - .w-sdc-distribution-view-content-section { - ul { - list-style-type: none; - } - - .distribution-bth { - .hand; - &.disabled { - cursor: none; - } - } - - .copy-link { - padding-right: 19px; - margin-left: 8px; - cursor: pointer; - - } - - .w-sdc-distribute-row-extends { - border-Left: solid 4px transparent; - &.extends { - border-left: solid 4px @main_color_c; - border-bottom: 1px solid @border_color_f; - margin-bottom: 10px; - } - } - .w-sdc-distribute-parent-block { - border: 1px solid @main_color_o;; - width: 100%; - margin-bottom: 6px; - - .status-icon { - vertical-align: middle; - margin-bottom: 4px; - } - - &.extends { - background-color: @tlv_color_t; - } - - :not(.disable-hover):hover { - background-color: @tlv_color_u; - } - - .title-section { - display: inline-block; - margin-right: 10px; - flex-basis: 0; - } - - .title { - .l_12_m; - font-weight: bold; - } - .w-sdc-distribute-content { - display: flex; - align-items: center; - justify-content: space-between; - margin-left: 10px; - } - - .w-sdc-distribution-arrow-btn { - .sprite-new; - .arrow-up-small; - margin: 0 6px; - display: inline-table; - } - .extends.w-sdc-distribution-arrow-btn { - -webkit-transform: rotate(180deg); - -ms-transform: rotate(180deg); - transform: rotate(180deg); - } - - .w-sdc-distribute-row { - display: flex; - align-items: center; - justify-content: space-between; - - .w-sdc-distribute-row-content { - margin: 15px 31px 10px 0; - width: 100%; - .w-sdc-distribute-status-block { - border-top: solid 1px @main_color_o; - } - .item-1 { - flex-grow: 2; - } - .item-2 { - flex-grow: 1; - } - .item-3 { - flex-grow: 1; - } - .item-4 { - flex-grow: 1; - } - .item-5 { - flex-grow: 1; - } - } - } - - .w-sdc-distribute-status-block { - display: flex; - align-items: center; - justify-content: space-between; - margin: 10px 5px 0 5px; - padding: 5px 5px 0 5px;; - width: 100%; - div { - border-left: 1px solid @main_color_o; - padding: 0 12px; - } - - .link { - .a_14_m; - cursor: pointer; - &:hover{ - text-decoration: underline; - .b_14_m; - } - } - - span { - padding: 2px; - } - - .deployed { - margin-left: 10px; - .sprite-new; - .success-circle-small; - } - - .error { - .q_14_m; - margin-left: 10px; - .sprite-new; - .error-icon; - } - - .status-item-1 { - border-left: 0; - } - - .status-item-6 { - flex-grow: 1; - border-left: none; - text-align: right; - } - } - - .w-sdc-distribute-components-block { - padding: 0; - padding-bottom: 5px; - list-style-type: none; - - li { - margin: 5px 2px; - } - - .omf-component-row { - border: 1px solid @border_color_f; - padding-left: 3px; - background-color: white; - margin: 0 30px; - &.extends { - padding-left: 0; - border-Left: solid 4px @main_color_c; - - } - - .w-sdc-distribute-status-block { - margin: 5px; - padding: 5px; - } - - .blue-font { - .a_16_m; - - } - - &:hover { - background-color: @tlv_color_u; - } - - } - - } - - .w-sdc-distribute-omfComponent-block { - background-color: white; - margin: 0 30px; - padding: 8px 10px; - border: 1px solid @border_color_f; - - .omfComponent-table-head { - margin-bottom: 5px; - background-color: @tlv_color_u; - .title { - padding: 6px 10px; - border-left: 1px solid @border_color_f; - &:first-child { - border: none; - } - } - } - - .omfComponent-table-row { - border-bottom: 1px solid @border_color_f; - &.row-0 { - border-top: 1px solid @border_color_f; - } - .w-sdc-distribute-cell { - padding: 10px; - border-left: 1px solid @border_color_f; - &:last-child { - border-right: 1px solid @border_color_f; - } - &.item-5 { - .m_14_m; - } - } - } - - .distribution-url { - - } - - .w-sdc-distribute-row.extends { - border-Left: solid 4px @main_color_c; - .item-1 { - border: none; - } - - } - - .item-1 { - width: 20%; - } - .item-2 { - width: 20%; - } - - .item-3 { - width: 24%; - display: flex; - } - - .item-4 { - width: 18%; - } - - .item-5 { - width: 18%; - } - } - - .w-sdc-distribute-url-block { - - padding: 10px 15px; - border: none; - border-right: 1px solid @border_color_f; - border-bottom: 1px solid @border_color_f; - width: 100%; - li { - border: none; - span { - padding-right: 30px; - .m_12_r; - } - } - - } - } - - } -} - diff --git a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts index b4529700cf..e2709281b7 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts +++ b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view-model.ts @@ -7,9 +7,9 @@ * 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. @@ -22,11 +22,13 @@ import * as _ from "lodash"; import {ModalsHandler, ValidationUtils, EVENTS, CHANGE_COMPONENT_CSAR_VERSION_FLAG, ComponentType, DEFAULT_ICON, ResourceType, ComponentState, instantiationType, ComponentFactory} from "app/utils"; -import {CacheService, EventListenerService, ProgressService, OnboardingService} from "app/services"; +import { EventListenerService, ProgressService} from "app/services"; +import {CacheService, OnboardingService, ImportVSPService} from "app/services-ng2"; import {IAppConfigurtaion, IValidate, IMainCategory, Resource, ISubCategory,Service, ICsarComponent, Component} from "app/models"; import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model"; import {Dictionary} from "lodash"; import { PREVIOUS_CSAR_COMPONENT } from "../../../../utils/constants"; +import { Observable, Subject } from "rxjs"; export class Validation { @@ -37,7 +39,6 @@ export class Validation { VendorNameValidationPattern:RegExp; VendorModelNumberValidationPattern:RegExp; commentValidationPattern:RegExp; - projectCodeValidationPattern:RegExp; } export class componentCategories {//categories field bind to this obj in order to solve this bug: DE242059 @@ -61,7 +62,7 @@ export interface IGeneralScope extends IWorkspaceViewModelScope { isShowFileBrowse:boolean; isShowOnboardingSelectionBrowse:boolean; importedToscaBrowseFileText:string; - importCsarProgressKey:string; + importCsarProProgressKey:string; browseFileLabel:string; componentCategories:componentCategories; instantiationTypes:Array; @@ -86,6 +87,7 @@ export interface IGeneralScope extends IWorkspaceViewModelScope { possibleToUpdateIcon():boolean; } +// tslint:disable-next-line:max-classes-per-file export class GeneralViewModel { static '$inject' = [ @@ -100,7 +102,6 @@ export class GeneralViewModel { 'CommentValidationPattern', 'ValidationUtils', 'sdcConfig', - 'ProjectCodeValidationPattern', '$state', 'ModalsHandler', 'EventListenerService', @@ -109,8 +110,10 @@ export class GeneralViewModel { '$interval', '$filter', '$timeout', - 'Sdc.Services.OnboardingService', - 'ComponentFactory' + 'OnboardingService', + 'ComponentFactory', + 'ImportVSPService', + '$stateParams' ]; constructor(private $scope:IGeneralScope, @@ -124,7 +127,6 @@ export class GeneralViewModel { private CommentValidationPattern:RegExp, private ValidationUtils:ValidationUtils, private sdcConfig:IAppConfigurtaion, - private ProjectCodeValidationPattern:RegExp, private $state:ng.ui.IStateService, private ModalsHandler:ModalsHandler, private EventListenerService:EventListenerService, @@ -133,8 +135,10 @@ export class GeneralViewModel { protected $interval:any, private $filter:ng.IFilterService, private $timeout:ng.ITimeoutService, - private onBoardingService:OnboardingService, - private ComponentFactory:ComponentFactory) { + private onBoardingService: OnboardingService, + private ComponentFactory:ComponentFactory, + private importVSPService: ImportVSPService, + private $stateParams: any) { this.initScopeValidation(); this.initScopeMethods(); @@ -153,13 +157,11 @@ export class GeneralViewModel { this.$scope.validation.VendorNameValidationPattern = this.VendorNameValidationPattern; this.$scope.validation.VendorModelNumberValidationPattern = this.VendorModelNumberValidationPattern; this.$scope.validation.commentValidationPattern = this.CommentValidationPattern; - this.$scope.validation.projectCodeValidationPattern = this.ProjectCodeValidationPattern; }; - private loadOnboardingFileCache = ():ng.IPromise> =>{ - + private loadOnboardingFileCache = (): Observable>> => { let onboardCsarFilesMap:Dictionary>; - let onSuccess = (vsps:Array) =>{ + let onSuccess = (vsps:Array) => { onboardCsarFilesMap = {}; _.each(vsps, (vsp:ICsarComponent)=>{ onboardCsarFilesMap[vsp.packageId] = onboardCsarFilesMap[vsp.packageId] || {}; @@ -170,8 +172,8 @@ export class GeneralViewModel { }; let onError = (): void =>{ console.log("Error getting onboarding list"); - }; - return this.onBoardingService.getOnboardingVSPs().then(onSuccess, onError); + }; + return this.onBoardingService.getOnboardingVSPs().map(onSuccess, onError); }; private setImportedFileText = ():void => { @@ -179,7 +181,7 @@ export class GeneralViewModel { if(!this.$scope.isShowOnboardingSelectionBrowse) return; //these variables makes it easier to read this logic - let csarUUID:string = (this.$scope.component).csarUUID; + let csarUUID:string = (this.$scope.component).csarUUID; let csarVersion:string = (this.$scope.component).csarVersion; let onboardCsarFilesMap:Dictionary> = this.cacheService.get('onboardCsarFilesMap'); @@ -187,21 +189,25 @@ export class GeneralViewModel { if(this.$scope.component.vspArchived){ this.$scope.importedToscaBrowseFileText = 'VSP is archived'; } else { - this.$scope.importedToscaBrowseFileText = onboardCsarFilesMap[csarUUID][csarVersion]; + if(this.$stateParams.componentCsar && this.$scope.component.lifecycleState === 'NOT_CERTIFIED_CHECKIN' && !this.$scope.isCreateMode()) { + this.$scope.importedToscaBrowseFileText = this.$scope.originComponent.name + ' (' + (this.$scope.originComponent as Resource).csarVersion + ')'; + } else { + this.$scope.importedToscaBrowseFileText = onboardCsarFilesMap[csarUUID][csarVersion]; + } } } - + if(this.$scope.component.vspArchived || (onboardCsarFilesMap && onboardCsarFilesMap[csarUUID] && onboardCsarFilesMap[csarUUID][csarVersion])){ //check that the file name is already in cache assignFileName(); } else { - this.loadOnboardingFileCache().then((onboardingFiles) => { + this.loadOnboardingFileCache().subscribe((onboardingFiles) => { onboardCsarFilesMap = onboardingFiles; this.cacheService.set('onboardCsarFilesMap', onboardingFiles); assignFileName(); }, ()=> {}); } - + } isCreateModeAvailable(verifyObj:string): boolean { @@ -211,10 +217,9 @@ export class GeneralViewModel { private initScope = ():void => { - this.$scope.importCsarProgressKey = "importCsarProgressKey"; - this.$scope.browseFileLabel = this.$scope.component.isResource() && (this.$scope.component).resourceType === ResourceType.VF ? "Upload file" : "Upload VFC"; + this.$scope.browseFileLabel = this.$scope.component.isResource() && (this.$scope.component).resourceType === ResourceType.VF ? 'VSP' : 'Upload VFC'; this.$scope.progressService = this.progressService; this.$scope.componentCategories = new componentCategories(); this.$scope.componentCategories.selectedCategory = this.$scope.component.selectedCategory; @@ -236,7 +241,7 @@ export class GeneralViewModel { if (resource.importedFile) { // Component has imported file. this.$scope.isShowFileBrowse = true; } - if (this.$scope.isEditMode() && resource.resourceType == ResourceType.VF && !resource.csarUUID) { + if (resource.resourceType === ResourceType.VF && !resource.csarUUID) { this.$scope.isShowFileBrowse = true; } } else if(this.$scope.component.isService()){ @@ -244,30 +249,35 @@ export class GeneralViewModel { this.$scope.initInstantiationTypes(); } - // Work around to change the csar version - if (this.cacheService.get(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) { - //(this.$scope.component).csarVersion = this.cacheService.get(CHANGE_COMPONENT_CSAR_VERSION_FLAG); - this.cacheService.remove(CHANGE_COMPONENT_CSAR_VERSION_FLAG); - this.$scope.updateUnsavedFileFlag(true); + if (this.cacheService.get(PREVIOUS_CSAR_COMPONENT)) { //keep the old component in the cache until checkout, so we dont need to pass it around + this.$scope.setOriginComponent(this.cacheService.get(PREVIOUS_CSAR_COMPONENT)); + this.cacheService.remove(PREVIOUS_CSAR_COMPONENT); + } - if (!this.$scope.isViewMode() && this.cacheService.get(PREVIOUS_CSAR_COMPONENT)) { //keep the old component in the cache until checkout, so we dont need to pass it around - this.$scope.setOriginComponent(this.cacheService.get(PREVIOUS_CSAR_COMPONENT)); - this.cacheService.remove(PREVIOUS_CSAR_COMPONENT); + if (this.$stateParams.componentCsar && !this.$scope.isCreateMode()) { + this.$scope.updateUnsavedFileFlag(true); + // We are coming from update VSP modal we need to automatically checkout (if needed) and save the VF + if (this.$scope.component.lifecycleState !== ComponentState.NOT_CERTIFIED_CHECKOUT) { + // Checkout is needed after that a save will be invoked in workspace-view.handleLifeCycleStateChange + this.EventListenerService.notifyObservers(EVENTS.ON_LIFECYCLE_CHANGE_WITH_SAVE, 'checkOut'); + // if(this.$scope.component.lifecycleState !== 'NOT_CERTIFIED_CHECKIN') { + // (this.$scope.component).csarVersion = this.$stateParams.componentCsar.csarVersion; + // } + } else { + this.$scope.save(); } } - // Init the decision if to show onboarding - if (this.$scope.component.isResource() && this.$scope.isEditMode() && - ((this.$scope.component).resourceType == ResourceType.VF || - (this.$scope.component).resourceType == ResourceType.PNF) - && (this.$scope.component).csarUUID) { + if (this.$scope.component.isResource() && + (this.$scope.component as Resource).resourceType === ResourceType.VF || + (this.$scope.component as Resource).resourceType === ResourceType.PNF && (this.$scope.component as Resource).csarUUID) { this.$scope.isShowOnboardingSelectionBrowse = true; this.setImportedFileText(); } else { this.$scope.isShowOnboardingSelectionBrowse = false; } - + //init file extensions based on the file that was imported. if (this.$scope.component.isResource() && (this.$scope.component).importedFile) { @@ -304,7 +314,7 @@ export class GeneralViewModel { this.$scope.originComponent.contactId = this.$scope.component.contactId; } - + this.$scope.$on('$destroy', () => { this.EventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE_WITH_SAVE); this.EventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE); @@ -313,7 +323,7 @@ export class GeneralViewModel { }; // Convert category string MainCategory_#_SubCategory to Array with one item (like the server except) - private convertCategoryStringToOneArray = ():Array => { + private convertCategoryStringToOneArray = ():IMainCategory[] => { let tmp = this.$scope.component.selectedCategory.split("_#_"); let mainCategory = tmp[0]; let subCategory = tmp[1]; @@ -333,14 +343,14 @@ export class GeneralViewModel { } let tmpSelected = mainCategoryClone; - let result:Array = []; + let result:IMainCategory[] = []; result.push(tmpSelected); return result; }; private updateComponentNameInBreadcrumbs = ():void => { - //update breadcrum after changing name + // update breadcrum after changing name this.$scope.breadcrumbsModel[1].updateSelectedMenuItemText(this.$scope.component.getComponentSubType() + ': ' + this.$scope.component.name); this.$scope.updateMenuComponentName(this.$scope.component.name); }; @@ -436,24 +446,20 @@ export class GeneralViewModel { if(this.$scope.component.vspArchived) return; let csarUUID = (this.$scope.component).csarUUID; let csarVersion = (this.$scope.component).csarVersion; - this.ModalsHandler.openOnboadrdingModal('Update', csarUUID, csarVersion).then((result)=> { - - if(result){ - this.ComponentFactory.getComponentWithMetadataFromServer(result.type.toUpperCase(), result.previousComponent.uniqueId).then( - (component:Component)=> { - if (result.componentCsar && component.isResource()){ - this.cacheService.set(PREVIOUS_CSAR_COMPONENT, angular.copy(component)); - component = this.ComponentFactory.updateComponentFromCsar(result.componentCsar, component); - } - - this.$scope.setComponent(component); - this.$scope.updateUnsavedFileFlag(true); - this.setImportedFileText(); - }, ()=> { - // ERROR - }); - } - }, () => {}); + this.importVSPService.openOnboardingModal(csarUUID, csarVersion).subscribe((result) => { + this.ComponentFactory.getComponentWithMetadataFromServer(result.type.toUpperCase(), result.previousComponent.uniqueId).then( + (component:Component)=> { + if (result.componentCsar && component.isResource()){ + this.cacheService.set(PREVIOUS_CSAR_COMPONENT, angular.copy(component)); + component = this.ComponentFactory.updateComponentFromCsar(result.componentCsar, component); + } + this.$scope.setComponent(component); + this.$scope.save(); + this.setImportedFileText(); + }, ()=> { + // ERROR + }); + }) }; this.$scope.updateIcon = ():void => { @@ -491,17 +497,17 @@ export class GeneralViewModel { return; } - let subtype:string = ComponentType.RESOURCE == this.$scope.componentType ? this.$scope.component.getComponentSubType() : undefined; + const subtype:string = ComponentType.RESOURCE == this.$scope.componentType ? this.$scope.component.getComponentSubType() : undefined; - let onFailed = (response) => { - //console.info('onFaild', response); - //this.$scope.isLoading = false; + const onFailed = (response) => { + // console.info('onFaild', response); + // this.$scope.isLoading = false; }; - let onSuccess = (validation:IValidate) => { - this.$scope.editForm["componentName"].$setValidity('nameExist', validation.isValid); + const onSuccess = (validation:IValidate) => { + this.$scope.editForm['componentName'].$setValidity('nameExist', validation.isValid); if (validation.isValid) { - //update breadcrumb after changing name + // update breadcrumb after changing name this.updateComponentNameInBreadcrumbs(); } }; @@ -522,48 +528,57 @@ export class GeneralViewModel { && !this.$scope.editForm["componentName"].$error.pattern && (!this.$scope.originComponent.name || this.$scope.component.name.toUpperCase() !== this.$scope.originComponent.name.toUpperCase()) ) { - if (!(this.$scope.componentType === ComponentType.RESOURCE && (this.$scope.component).csarUUID !== undefined) + if (!(this.$scope.componentType === ComponentType.RESOURCE && (this.$scope.component as Resource).csarUUID !== undefined) ) { this.$scope.component.validateName(name, subtype).then(onSuccess, onFailed); } - } else if (this.$scope.originComponent.name && this.$scope.component.name.toUpperCase() === this.$scope.originComponent.name.toUpperCase()) { + } else if (this.$scope.editForm && this.$scope.originComponent.name && this.$scope.component.name.toUpperCase() === this.$scope.originComponent.name.toUpperCase()) { // Clear the error - this.$scope.editForm["componentName"].$setValidity('nameExist', true); + this.$scope.editForm['componentName'].$setValidity('nameExist', true); } } }; this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE_WITH_SAVE, (nextState) => { - if (this.$state.current.data.unsavedChanges && this.$scope.isValidForm){ + if (this.$state.current.data.unsavedChanges && this.$scope.isValidForm) { this.$scope.save().then(() => { this.$scope.handleChangeLifecycleState(nextState); }, () => { - console.error("Save failed, unable to change lifecycle state to " + nextState); + console.error('Save failed, unable to change lifecycle state to ' + nextState); }); } else if(!this.$scope.isValidForm){ - console.error("Form is not valid"); + console.error('Form is not valid'); } else { let newCsarVersion:string; - if(this.$scope.unsavedFile){ - newCsarVersion = (this.$scope.component).csarVersion; + if(this.$scope.unsavedFile) { + newCsarVersion = (this.$scope.component as Resource).csarVersion; + } + if(this.$stateParams.componentCsar && !this.$scope.isCreateMode()) { + const onError = (): void => { + if (this.$scope.component.lifecycleState === 'NOT_CERTIFIED_CHECKIN') { + this.$scope.revert(); + } + }; + this.$scope.handleChangeLifecycleState(nextState, newCsarVersion, onError); + + } else { + this.$scope.handleChangeLifecycleState(nextState, newCsarVersion); } - this.$scope.handleChangeLifecycleState(nextState, newCsarVersion); } }); - this.$scope.revert = ():void => { - //in state of import file leave the file in place + // in state of import file leave the file in place this.$scope.setComponent(this.ComponentFactory.createComponent(this.$scope.originComponent)); if (this.$scope.component.isResource() && this.$scope.restoreFile) { - (this.$scope.component).importedFile = angular.copy(this.$scope.restoreFile); - } - - this.setImportedFileText(); - this.$scope.updateBreadcrumbs(this.$scope.component); //update on workspace + (this.$scope.component as Resource).importedFile = angular.copy(this.$scope.restoreFile); + } + + this.setImportedFileText(); + this.$scope.updateBreadcrumbs(this.$scope.component); // update on workspace this.$scope.componentCategories.selectedCategory = this.$scope.originComponent.selectedCategory; this.setUnsavedChanges(false); @@ -573,8 +588,8 @@ export class GeneralViewModel { this.$scope.onImportFileChange = () => { - if( !this.$scope.restoreFile && this.$scope.editForm.fileElement.value && this.$scope.editForm.fileElement.value.filename || //if file started empty but we have added a new one - this.$scope.restoreFile && !angular.equals(this.$scope.restoreFile, this.$scope.editForm.fileElement.value)){ //or file was swapped for a new one + if( !this.$scope.restoreFile && this.$scope.editForm.fileElement.value && this.$scope.editForm.fileElement.value.filename || // if file started empty but we have added a new one + this.$scope.restoreFile && !angular.equals(this.$scope.restoreFile, this.$scope.editForm.fileElement.value)){ // or file was swapped for a new one this.$scope.updateUnsavedFileFlag(true); } else { this.$scope.updateUnsavedFileFlag(false); @@ -582,46 +597,46 @@ export class GeneralViewModel { } }; - this.$scope.$watchCollection('component.name', (newData:any):void => { + this.$scope.$watchCollection('component.name', (newData: any): void => { this.$scope.validateName(false); }); // Notify the parent if this step valid or not. - this.$scope.$watch("editForm.$valid", (newVal, oldVal) => { + this.$scope.$watch('editForm.$valid', (newVal, oldVal) => { this.$scope.setValidState(newVal); }); - this.$scope.$watch("editForm.$dirty", (newVal, oldVal) => { + this.$scope.$watch('editForm.$dirty', (newVal, oldVal) => { if (newVal && !this.$scope.isCreateMode()) { this.setUnsavedChanges(true); } }); - this.$scope.onCategoryChange = ():void => { + this.$scope.onCategoryChange = (): void => { this.$scope.component.selectedCategory = this.$scope.componentCategories.selectedCategory; this.$scope.component.categories = this.convertCategoryStringToOneArray(); this.$scope.component.icon = DEFAULT_ICON; }; - this.$scope.onEcompGeneratedNamingChange = ():void =>{ - if(!(this.$scope.component).ecompGeneratedNaming){ - (this.$scope.component).namingPolicy = ''; + this.$scope.onEcompGeneratedNamingChange = (): void => { + if (!(this.$scope.component as Service).ecompGeneratedNaming) { + (this.$scope.component as Service).namingPolicy = ''; } }; - this.$scope.onVendorNameChange = (oldVendorName:string):void => { + this.$scope.onVendorNameChange = (oldVendorName: string): void => { if (this.$scope.component.icon === oldVendorName) { this.$scope.component.icon = DEFAULT_ICON; } }; this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.$scope.reload); - }; + } - private setUnsavedChanges = (hasChanges:boolean):void => { + private setUnsavedChanges = (hasChanges: boolean): void => { this.$state.current.data.unsavedChanges = hasChanges; - }; + } } diff --git a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html index 07f1e4d6ed..86f1feba0c 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html +++ b/catalog-ui/src/app/view-models/workspace/tabs/general/general-view.html @@ -13,13 +13,12 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -
    -
    +
    Click save to update to the new VSP
    - @@ -160,7 +159,7 @@
    - + @@ -173,17 +172,17 @@ on-file-changed-in-directive="onImportFileChange" extensions="{{importedFileExtension}}" default-text="'Browse to select file'" - data-ng-class="{'error':!(isEditMode()&&component.resourceType=='VF') && (!editForm.fileElement.$valid || !component.importedFile.filename)}"> + >
    - +
    {{(fileModel && fileModel.filename) || importedToscaBrowseFileText }}
    - -
    Browse
    + +
    Browse
    @@ -218,28 +217,6 @@
    - -
    - - - -
    - - - -
    -
    -
    @@ -401,6 +378,27 @@
    + +
    + + +
    + + +
    +
    + +
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/general/general.less b/catalog-ui/src/app/view-models/workspace/tabs/general/general.less index b60e4b8de4..8b2cc01d75 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/general/general.less +++ b/catalog-ui/src/app/view-models/workspace/tabs/general/general.less @@ -27,6 +27,7 @@ .file-upload-browse-btn { .noselect; .bg_n; + color:#191919; padding: 4px 6px; cursor: pointer; z-index: 999; @@ -35,10 +36,6 @@ text-align: center; border-left: solid 1px #cfcfcf; - &.disabled { - cursor: default; - } - &:hover:not(.disabled) { background-color: #dbdee2; } diff --git a/catalog-ui/src/app/view-models/workspace/tabs/information-artifacts/information-artifacts-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/information-artifacts/information-artifacts-view-model.ts deleted file mode 100644 index 47a96fb385..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/information-artifacts/information-artifacts-view-model.ts +++ /dev/null @@ -1,158 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import * as _ from "lodash"; -import {ModalsHandler} from "app/utils"; -import {SharingService} from "app/services"; -import {IAppConfigurtaion, ArtifactModel, IFileDownload} from "app/models"; -import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model"; -import {ComponentServiceNg2} from "../../../../ng2/services/component-services/component.service"; -import {ArtifactGroupModel} from "../../../../models/artifacts"; -import {ComponentGenericResponse} from "../../../../ng2/services/responses/component-generic-response"; - -export interface IInformationArtifactsScope extends IWorkspaceViewModelScope { - artifacts:Array; - tableHeadersList:Array; - artifactType:string; - isResourceInstance:boolean; - downloadFile:IFileDownload; - isLoading:boolean; - sortBy:string; - reverse:boolean; - - getTitle():string; - addOrUpdate(artifact:ArtifactModel):void; - delete(artifact:ArtifactModel):void; - download(artifact:ArtifactModel):void; - clickArtifactName(artifact:any):void; - openEditEnvParametersModal(artifactResource:ArtifactModel):void; - sort(sortBy:string):void; - showNoArtifactMessage():boolean; -} - -export class InformationArtifactsViewModel { - - static '$inject' = [ - '$scope', - '$filter', - '$state', - 'sdcConfig', - 'ModalsHandler', - 'ComponentServiceNg2' - ]; - - constructor(private $scope:IInformationArtifactsScope, - private $filter:ng.IFilterService, - private $state:any, - private sdcConfig:IAppConfigurtaion, - private ModalsHandler:ModalsHandler, - private ComponentServiceNg2: ComponentServiceNg2) { - this.initInformationalArtifacts(); - } - - private initInformationalArtifacts = ():void => { - if(!this.$scope.component.artifacts) { - this.$scope.isLoading = true; - this.ComponentServiceNg2.getComponentInformationalArtifacts(this.$scope.component).subscribe((response:ComponentGenericResponse) => { - this.$scope.component.artifacts = response.artifacts; - this.initScope(); - this.$scope.isLoading = false; - }); - } else { - this.initScope(); - } - } - - private initScope = ():void => { - - this.$scope.isLoading = false; - this.$scope.sortBy = 'artifactDisplayName'; - this.$scope.reverse = false; - this.$scope.setValidState(true); - this.$scope.artifactType = 'informational'; - this.$scope.getTitle = ():string => { - return this.$filter("resourceName")(this.$scope.component.name) + ' Artifacts'; - - }; - - this.$scope.tableHeadersList = [ - {title: 'Name', property: 'artifactDisplayName'}, - {title: 'Type', property: 'artifactType'}, - {title: 'Version', property: 'artifactVersion'}, - {title: 'UUID', property: 'artifactUUID'} - ]; - - this.$scope.artifacts = _.values(this.$scope.component.artifacts); - this.$scope.sort = (sortBy:string):void => { - this.$scope.reverse = (this.$scope.sortBy === sortBy) ? !this.$scope.reverse : false; - this.$scope.sortBy = sortBy; - }; - - - this.$scope.addOrUpdate = (artifact:ArtifactModel):void => { - artifact.artifactGroupType = 'INFORMATIONAL'; - this.ModalsHandler.openArtifactModal(artifact, this.$scope.component).then(() => { - this.$scope.artifacts = _.values(this.$scope.component.artifacts); - }); - }; - - this.$scope.showNoArtifactMessage = ():boolean => { - let artifacts:any = []; - artifacts = _.filter(this.$scope.artifacts, (artifact:ArtifactModel)=> { - return artifact.esId; - }); - - if (artifacts.length === 0) { - return true; - } - return false; - }; - - this.$scope.delete = (artifact:ArtifactModel):void => { - - let onOk = ():void => { - this.$scope.isLoading = true; - let onSuccess = ():void => { - this.$scope.isLoading = false; - this.$scope.artifacts = _.values(this.$scope.component.artifacts); - }; - - let onFailed = (error:any):void => { - console.log('Delete artifact returned error:', error); - this.$scope.isLoading = false; - }; - - this.$scope.component.deleteArtifact(artifact.uniqueId, artifact.artifactLabel).then(onSuccess, onFailed); - }; - - let title:string = this.$filter('translate')("ARTIFACT_VIEW_DELETE_MODAL_TITLE"); - let message:string = this.$filter('translate')("ARTIFACT_VIEW_DELETE_MODAL_TEXT", "{'name': '" + artifact.artifactDisplayName + "'}"); - this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk); - }; - - this.$scope.clickArtifactName = (artifact:any) => { - if (!artifact.esId) { - this.$scope.addOrUpdate(artifact); - } - - }; - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/information-artifacts/information-artifacts-view.html b/catalog-ui/src/app/view-models/workspace/tabs/information-artifacts/information-artifacts-view.html deleted file mode 100644 index eacadb376c..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/information-artifacts/information-artifacts-view.html +++ /dev/null @@ -1,82 +0,0 @@ - - -
    -
    Add
    -
    -
    -
    -
    {{header.title}} - -
    -
    -
    -
    - -
    - There are no information artifacts to display -
    -
    - -
    - - {{artifact.artifactDisplayName}} -
    - -
    - {{artifact.artifactType}} -
    - -
    - {{artifact.artifactVersion}} -
    - -
    - {{artifact.artifactUUID}} -
    - -
    - - - -
    -
    -
    - - -
    -
    -
    -
    -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/information-artifacts/information-artifacts.less b/catalog-ui/src/app/view-models/workspace/tabs/information-artifacts/information-artifacts.less deleted file mode 100644 index 5e69c44e9b..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/information-artifacts/information-artifacts.less +++ /dev/null @@ -1,57 +0,0 @@ -.workspace-information-artifact { - width: 93%; - display: inline-block; - .w-sdc-classic-btn { - float: right; - margin-bottom: 10px; - } - - .table{ - height: 490px; - margin-bottom: 0; - } - - .table-container-flex { - margin-top: 0; - - .item-opened{ - word-wrap: break-word; - } - - .text{ - overflow: hidden; - text-overflow: ellipsis; - display: inline-block; - white-space: nowrap; - } - - .flex-item:nth-child(1) { - flex-grow: 15; - .hand; - span.table-arrow { - margin-right: 7px; - } - } - - .flex-item:nth-child(2) { - flex-grow: 6; - } - - .flex-item:nth-child(3) { - flex-grow: 3; - } - - .flex-item:nth-child(4) { - flex-grow: 20; - } - - .flex-item:nth-child(5) { - flex-grow: 5; - padding-top: 10px; - } - - } - -} - - diff --git a/catalog-ui/src/app/view-models/workspace/tabs/inputs/inputs.less b/catalog-ui/src/app/view-models/workspace/tabs/inputs/inputs.less deleted file mode 100644 index 17c18e1741..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/inputs/inputs.less +++ /dev/null @@ -1,225 +0,0 @@ -.workspace-inputs { - - .sdc-workspace-container .w-sdc-main-right-container .w-sdc-main-container-body-content { - padding: 25px 8% 25px 8%; - } - - .w-sdc-main-container .w-sdc-main-right-container > div:first-child { - /* scroll fix */ - padding-bottom: 0px; - } - - - width: 100%; - display: flex; - - .text { - padding-left: 15px; - .no-overflow; - } - - .title-text { - color: @main_color_m; - .f-type._13_m; - .bold; - text-overflow: ellipsis; - overflow: hidden; - } - - .no-overflow { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - } - - .title-blue-text { - color: @main_color_a; - .f-type._13_m; - - &.property-name-text { - padding-right: 13px; - border-right: 1px solid rgba(120, 136, 148, 0.26); - flex-grow: 1; - .no-overflow; - } - } - - .instance-name-text { - flex-grow: 1; - } - - ng-include { - width: 45%; - } - - .w-sdc-inputs-search { - padding: 10px 20px 20px 0; - white-space: nowrap; - position: relative; - width: 60%; - height: 64px; - - .inputs-search-icon { - top: 9px; - right: 11px; - } - - .magnification-white { - .sprite-new; - .search-white-icon; - .hand; - } - - .search-icon-container { - width: 35px; - height: 30px; - background-color: @main_color_a; - white-space: nowrap; - float: right; - position: relative; - bottom: 31px; - right: 1px; - border-radius: 0px 4px 4px 0px; - .hand - } - } - - .total-inputs-count { - width: 100%; - font-weight: bold; - text-align: left; - } - - .new-input-button { - margin: 9px 0 0 0; - } - - .w-sdc-inputs-search-input { - border: 1px solid @color_e; - .border-radius(4px); - height: 32px; - margin: 0; - padding: 0px 28px 3px 10px; - vertical-align: 4px; - width: 100%; - outline: none; - font-style: italic; - } - - .w-sdc-classic-btn { - float: right; - margin-bottom: 10px; - } - - .prop-to-input-button { - position: absolute; - top: 50%; - margin-right: -20px; - margin-bottom: -10px; - - } - - .table-container-flex { - - .flex-item { - line-height: 22px; - } - .expand-collapse-table-row { - - .data-row { - background: @tlv_color_u; - .hand; - align-items: center; - padding: 0 12px; - margin: 1px 0px 1px 0px; - min-height: 40px; - } - - .data-row:hover { - .bg_j; - } - } - } - - .table { - height: 640px; - margin-bottom: 0; - clear: both; - - .empty-row { - padding: 3px; - } - - .flex-item { - line-height: 22px; - } - - .table-header { - - line-height: 14px; - background-color: @main_color_a; - color: @main_color_p; - text-align: left; - padding: 7px 5px 7px 10px; - .f-type._14_m; - } - .head { - background-color: #e6e6e6; - } - - .body { - .scrollbar-container { - .perfect-scrollbar; - max-height: 610px; - } - - .expand-collapse-inputs-table-icon { - .hand; - .sprite-new; - .arrow-up; - transition: .3s all; - position: relative; - left: 8px; - border: none !important; - padding: 0px 10px 0px 10px; - } - - .table-col-text { - margin-left: 14px; - } - } - } - - .inputs-header { - width: 100%; - position: relative; - bottom: 31px; - } - - .inputs-tables-container { - width: 100%; - min-width: 100%; - display: flex; - } - - .inputs-button-container { - width: 8%; - min-width: 8%; - display: flex; - - .right-arrow-btn { - .sprite-new; - .blue-right-arrow-circle; - margin: auto; - cursor: pointer; - } - } - - .table-container-flex { - margin-top: 0; - width: 46%; - min-width: 46%; - display: inline-block; - float: left; - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/interface-operation/interface-operation-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/interface-operation/interface-operation-view-model.ts index 180d78954a..83a2be2a60 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/interface-operation/interface-operation-view-model.ts +++ b/catalog-ui/src/app/view-models/workspace/tabs/interface-operation/interface-operation-view-model.ts @@ -27,7 +27,6 @@ * limitations under the License. */ - 'use strict'; import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model"; diff --git a/catalog-ui/src/app/view-models/workspace/tabs/interface-operation/interface-operation-view.html b/catalog-ui/src/app/view-models/workspace/tabs/interface-operation/interface-operation-view.html index 0e7c355c47..236289feff 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/interface-operation/interface-operation-view.html +++ b/catalog-ui/src/app/view-models/workspace/tabs/interface-operation/interface-operation-view.html @@ -13,7 +13,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -
    -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/network-call-flow/network-call-flow-view.html b/catalog-ui/src/app/view-models/workspace/tabs/network-call-flow/network-call-flow-view.html index a1efb33301..01343a35ac 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/network-call-flow/network-call-flow-view.html +++ b/catalog-ui/src/app/view-models/workspace/tabs/network-call-flow/network-call-flow-view.html @@ -13,7 +13,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/plugins/plugins-context-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/plugins/plugins-context-view-model.ts deleted file mode 100644 index d3ccbe3325..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/plugins/plugins-context-view-model.ts +++ /dev/null @@ -1,94 +0,0 @@ -/* - -* Copyright (c) 2018 AT&T Intellectual Property. - -* - -* 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. - -*/ - -import {IUserProperties, Plugin} from "app/models"; -import {CacheService} from "app/services"; -import {PluginsService} from "../../../../ng2/services/plugins.service"; -import {IWorkspaceViewModelScope} from "../../workspace-view-model"; - - -interface IPluginsContextViewModelScope extends IWorkspaceViewModelScope { - plugin: Plugin; - user: IUserProperties; - queryParams: Object; - isLoading: boolean; - show: boolean; - - onLoadingDone(plugin: Plugin): void; -} - -export class PluginsContextViewModel { - static '$inject' = [ - '$scope', - '$stateParams', - 'Sdc.Services.CacheService', - 'PluginsService' - ]; - - constructor(private $scope: IPluginsContextViewModelScope, - private $stateParams: any, - private cacheService: CacheService, - private pluginsService: PluginsService) { - - this.initScope(); - } - - private initScope = (): void => { - this.$scope.show = false; - this.$scope.plugin = this.pluginsService.getPluginByStateUrl(this.$stateParams.path); - this.$scope.user = this.cacheService.get('user'); - - this.$scope.isLoading = true; - - this.$scope.queryParams = { - userId: this.$scope.user.userId, - userRole: this.$scope.user.role, - displayType: "context", - contextType: this.$scope.component.getComponentSubType(), - uuid: this.$scope.component.uuid, - lifecycleState: this.$scope.component.lifecycleState, - isOwner: this.$scope.component.lastUpdaterUserId === this.$scope.user.userId, - version: this.$scope.component.version, - parentUrl: window.location.origin, - eventsClientId: this.$scope.plugin.pluginId - }; - - if (this.$stateParams.queryParams) { - _.assign(this.$scope.queryParams, this.$stateParams.queryParams); - } - - this.$scope.onLoadingDone = (plugin: Plugin) => { - if (plugin.pluginId == this.$scope.plugin.pluginId) { - this.$scope.isLoading = false; - } - }; - - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/plugins/plugins-context-view.html b/catalog-ui/src/app/view-models/workspace/tabs/plugins/plugins-context-view.html deleted file mode 100644 index 44c04e4e71..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/plugins/plugins-context-view.html +++ /dev/null @@ -1,20 +0,0 @@ - - - -
    - -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/plugins/plugins-context.less b/catalog-ui/src/app/view-models/workspace/tabs/plugins/plugins-context.less deleted file mode 100644 index c913af1931..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/plugins/plugins-context.less +++ /dev/null @@ -1,2 +0,0 @@ -.workspace-plugins { -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/properties/properties-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/properties/properties-view-model.ts index b09662d7a2..9794209757 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/properties/properties-view-model.ts +++ b/catalog-ui/src/app/view-models/workspace/tabs/properties/properties-view-model.ts @@ -19,12 +19,12 @@ */ 'use strict'; -import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model"; -import {PropertyModel} from "app/models"; -import {ModalsHandler} from "app/utils"; -import {COMPONENT_FIELDS} from "../../../../utils/constants"; -import {ComponentGenericResponse} from "../../../../ng2/services/responses/component-generic-response"; -import {ComponentServiceNg2} from "../../../../ng2/services/component-services/component.service"; +import { IWorkspaceViewModelScope } from "app/view-models/workspace/workspace-view-model"; +import { PropertyModel } from "app/models"; +import { ModalsHandler } from "app/utils"; +import { ComponentGenericResponse } from "../../../../ng2/services/responses/component-generic-response"; +import { ComponentServiceNg2 } from "../../../../ng2/services/component-services/component.service"; +import { SdcUiCommon, SdcUiServices, SdcUiComponents } from "onap-ui-angular"; interface IPropertiesViewModelScope extends IWorkspaceViewModelScope { tableHeadersList:Array; @@ -43,14 +43,16 @@ export class PropertiesViewModel { '$scope', '$filter', 'ModalsHandler', - 'ComponentServiceNg2' + 'ComponentServiceNg2', + 'ModalServiceSdcUI' ]; constructor(private $scope:IPropertiesViewModelScope, private $filter:ng.IFilterService, private ModalsHandler:ModalsHandler, - private ComponentServiceNg2:ComponentServiceNg2) { + private ComponentServiceNg2:ComponentServiceNg2, + private modalService: SdcUiServices.ModalService) { this.initComponentProperties(); } @@ -101,12 +103,13 @@ export class PropertiesViewModel { this.$scope.delete = (property:PropertyModel):void => { - let onOk = ():void => { + let onOk: Function = ():void => { this.$scope.component.deleteProperty(property.uniqueId); }; let title:string = this.$filter('translate')("PROPERTY_VIEW_DELETE_MODAL_TITLE"); let message:string = this.$filter('translate')("PROPERTY_VIEW_DELETE_MODAL_TEXT", "{'name': '" + property.name + "'}"); - this.ModalsHandler.openConfirmationModal(title, message, false).then(onOk); + const okButton = {testId: "OK", text: "OK", type: SdcUiCommon.ButtonType.info, callback: onOk, closeModal: true} as SdcUiComponents.ModalButtonComponent; + this.modalService.openInfoModal(title, message, 'delete-modal', [okButton]); }; } } diff --git a/catalog-ui/src/app/view-models/workspace/tabs/properties/properties-view.html b/catalog-ui/src/app/view-models/workspace/tabs/properties/properties-view.html index 1505e8397d..1d8a2ff78c 100644 --- a/catalog-ui/src/app/view-models/workspace/tabs/properties/properties-view.html +++ b/catalog-ui/src/app/view-models/workspace/tabs/properties/properties-view.html @@ -13,7 +13,6 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> -
    Total Properties: {{component.properties.length}} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-editable-view.html b/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-editable-view.html deleted file mode 100644 index 566cc5fc2c..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-editable-view.html +++ /dev/null @@ -1,247 +0,0 @@ - - -
    - - -
    -
    -
    Requirements -
    -
    Capabilities -
    -
    -
    - -
    - - - {{mode === 'requirements' ? 'Add Requirement' : 'Add Capability'}} -
    -
    -
    - -
    -
    - - -
    {{mode === 'requirements' ? 'Add Requirement' : 'Add Capability'}}
    -
    -
    - -
    -
    -
    -
    - {{header.title}} - -
    -
    - -
    - -
    - There are no requirements to display - -
    -
    -
    -
    - {{(!req.isCreatedManually ? req.ownerName + '.' : '') + req.name}} -
    -
    - {{req.capability && cutToscaTypePrefix(req.capability, 'capabilities.')}} -
    -
    - {{req.node && cutToscaTypePrefix(req.node, "nodes.")}} -
    -
    - {{req.relationship && cutToscaTypePrefix(req.relationship, "relationships.")}} -
    -
    - {{req.minOccurrences}} - {{req.maxOccurrences}} -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - {{header.title}} - -
    -
    - -
    - -
    - There are no capabilities to display -
    -
    - -
    - - - {{(!capability.isCreatedManually ? capability.ownerName + '.' : '') + capability.name}} - -
    -
    - {{capability.type && cutToscaTypePrefix(capability.type, 'capabilities.')}} -
    - -
    -
    {{capability.description}} -
    -
    - -
    - {{capability.validSourceTypes.join(',')}} -
    - -
    - {{capability.minOccurrences}} - {{capability.maxOccurrences}} -
    - -
    - -
    -
    -
    -

    Properties

    -
    -
    -
    -
    - {{header.title}} - -
    -
    - -
    -
    -
    - {{property.name}} -
    -
    - {{property.type}} -
    -
    - {{property.schema.property.type}} -
    -
    - {{property.description}} -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - diff --git a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view-model.ts deleted file mode 100644 index 14b45cbdf3..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view-model.ts +++ /dev/null @@ -1,471 +0,0 @@ -/*- - * ============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 rcohen on 9/22/2016. - */ -'use strict'; -import * as _ from "lodash"; -import {ComponentRef} from '@angular/core'; -import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model"; -import {ModalsHandler, ResourceType} from "app/utils"; -import {ComponentType} from "app/utils/constants"; -import { - Capability, PropertyModel, Requirement, Resource, - RelationshipTypesMap, NodeTypesMap, CapabilityTypesMap -} from "app/models"; -import {ComponentGenericResponse} from "app/ng2/services/responses/component-generic-response"; -import {ComponentServiceNg2} from "app/ng2/services/component-services/component.service"; -import {ToscaTypesServiceNg2} from "app/ng2/services/tosca-types.service"; -import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component'; -import {ModalService} from 'app/ng2/services/modal.service'; -import {RequirementsEditorComponent} from 'app/ng2/pages/req-and-capabilities-editor/requirements-editor/requirements-editor.component'; -import {CapabilitiesEditorComponent} from 'app/ng2/pages/req-and-capabilities-editor/capabilities-editor/capabilities-editor.component'; -import {ModalService as ModalServiceSdcUI} from "sdc-ui/lib/angular/modals/modal.service"; -import {IModalConfig} from "sdc-ui/lib/angular/modals/models/modal-config"; -import {ModalButtonComponent} from "sdc-ui/lib/angular/components"; - -export class SortTableDefined { - reverse:boolean; - sortByField:string; -} - -class RequirementUI extends Requirement { - isCreatedManually: boolean; - - constructor(input: Requirement, componentUniqueId: string) { - super(input); - this.isCreatedManually = input.ownerId === componentUniqueId; - } -} -class CapabilityUI extends Capability { - isCreatedManually: boolean; - - constructor(input: Capability, componentUniqueId: string) { - super(input); - this.isCreatedManually = input.ownerId === componentUniqueId; - } -} - -interface IReqAndCapabilitiesViewModelScope extends IWorkspaceViewModelScope { - requirementsTableHeadersList:Array; - editableRequirementsTableHeadersList: Array; - capabilitiesTableHeadersList:Array; - editableCapabilitiesTableHeadersList: Array; - capabilityPropertiesTableHeadersList:Array; - requirementsSortTableDefined:SortTableDefined; - capabilitiesSortTableDefined:SortTableDefined; - propertiesSortTableDefined:SortTableDefined; - requirements: Array; - filteredRequirementsList: Array; - capabilities: Array; - filteredCapabilitiesList: Array; - mode:string; - filteredProperties:Array>; - searchText:string; - isEditable: boolean; - modalInstance: ComponentRef; - filter: {txt: string; show: boolean}; - - sort(sortBy: string, sortByTableDefined: SortTableDefined, autoCollapseCapabilitiesRows: boolean): void; - sortByIsCreatedManually(arrToSort: Array): Array; - updateProperty(property:PropertyModel, indexInFilteredProperties:number):void; - allCapabilitiesSelected(selected:boolean):void; - onAddBtnClicked(): void; - onEditRequirement(req: RequirementUI): void; - onEditCapability(cap: CapabilityUI): void; - onDeleteReq(event, req: RequirementUI): void; - onDeleteCap(event, cap: CapabilityUI): void; - onFilter(): void; - isListEmpty(): boolean; - onSwitchTab(): void; - onSearchIconClick(): void; - cutToscaTypePrefix(valToCut: string, textToStartCut: string): string; - isReadonly(): boolean; -} - -export class ReqAndCapabilitiesViewModel { - - static '$inject' = [ - '$scope', - '$filter', - 'ModalsHandler', - 'ComponentServiceNg2', - 'ToscaTypesServiceNg2', - 'ModalServiceNg2', - 'ModalServiceSdcUI' - ]; - - - constructor(private $scope:IReqAndCapabilitiesViewModelScope, - private $filter:ng.IFilterService, - private ModalsHandler:ModalsHandler, - private ComponentServiceNg2: ComponentServiceNg2, - private ToscaTypesServiceNg2: ToscaTypesServiceNg2, - private ModalServiceNg2: ModalService, - private ModalServiceSdcUI: ModalServiceSdcUI) { - - this.initCapabilitiesAndRequirements(); - this.fetchCapabilitiesRelatedData(); - } - - private initCapabilitiesAndRequirements = (): void => { - - this.$scope.isEditable = this.getIsEditableByComponentType(); - this.$scope.isLoading = true; - this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response: ComponentGenericResponse) => { - this.$scope.component.capabilities = response.capabilities; - this.$scope.component.requirements = response.requirements; - this.initScope(); - this.$scope.isLoading = false; - }, () => { - this.$scope.isLoading = false; - }); - - } - - private openEditPropertyModal = (property:PropertyModel, indexInFilteredProperties:number):void => { - //...because there is not be api - _.forEach(this.$scope.filteredProperties[indexInFilteredProperties], (prop:PropertyModel)=> { - prop.readonly = true; - }); - this.ModalsHandler.openEditPropertyModal(property, this.$scope.component, this.$scope.filteredProperties[indexInFilteredProperties], false, "component", this.$scope.component.uniqueId).then(() => { - - }); - }; - - private initScope = (currentMode = 'requirements'): void => { - this.$scope.isReadonly = (): boolean => { - return this.$scope.isViewMode() || !this.$scope.isDesigner(); - }; - this.$scope.filter = {txt: '', show: false}; - this.$scope.requirementsSortTableDefined = { - reverse: false, - sortByField: this.$scope.isEditable ? 'other' : 'name' - }; - this.$scope.capabilitiesSortTableDefined = { - reverse: false, - sortByField: this.$scope.isEditable ? 'other' : 'name' - }; - this.$scope.propertiesSortTableDefined = { - reverse: false, - sortByField: 'name' - }; - - this.$scope.setValidState(true); - this.$scope.requirementsTableHeadersList = [ - {title: 'Name', property: 'name'}, - {title: 'Capability', property: 'capability'}, - {title: 'Node', property: 'node'}, - {title: 'Relationship', property: 'relationship'}, - {title: 'Connected To', property: ''}, - {title: 'Occurrences', property: ''} - ]; - this.$scope.capabilitiesTableHeadersList = [ - {title: 'Name', property: 'name'}, - {title: 'Type', property: 'type'}, - {title: 'Description', property: ''}, - {title: 'Valid Source', property: ''}, - {title: 'Occurrences', property: ''} - ]; - this.$scope.editableRequirementsTableHeadersList = [ - {title: 'Name', property: 'name'}, - {title: 'Capability', property: 'capability'}, - {title: 'Node', property: 'node'}, - {title: 'Relationship', property: 'relationship'}, - {title: 'Occurrences', property: 'occurrences'}, - {title: 'â—â—â—', property: 'other'} - ]; - this.$scope.editableCapabilitiesTableHeadersList = [ - {title: 'Name', property: 'name'}, - {title: 'Type', property: 'type'}, - {title: 'Description', property: 'description'}, - {title: 'Valid Sources', property: 'valid-sources'}, - {title: 'Occurrences', property: 'occurrences'}, - {title: 'â—â—â—', property: 'other'} - ]; - this.$scope.capabilityPropertiesTableHeadersList = [ - {title: 'Name', property: 'name'}, - {title: 'Type', property: 'type'}, - {title: 'Schema', property: 'schema.property.type'}, - {title: 'Description', property: 'description'}, - ]; - this.$scope.filteredProperties = []; - - this.$scope.mode = currentMode; - this.$scope.requirements = []; - _.forEach(this.$scope.component.requirements, (req:Array, capName)=> { - let reqUIList: Array = _.map(req, reqObj => new RequirementUI(reqObj, this.$scope.component.uniqueId)); - this.$scope.requirements = this.$scope.requirements.concat(reqUIList); - }); - this.$scope.filteredRequirementsList = this.$scope.requirements; - - this.$scope.capabilities = []; - _.forEach(this.$scope.component.capabilities, (cap:Array, capName)=> { - let capUIList: Array = _.map(cap, capObj => new CapabilityUI(capObj, this.$scope.component.uniqueId)); - this.$scope.capabilities = this.$scope.capabilities.concat(capUIList); - }); - - this.$scope.sortByIsCreatedManually = (arrToSort: Array): Array => { - return arrToSort.sort((elem1: RequirementUI|CapabilityUI, elem2: RequirementUI|CapabilityUI) => +elem2.isCreatedManually - (+elem1.isCreatedManually)); - }; - this.$scope.filteredCapabilitiesList = this.$scope.sortByIsCreatedManually(this.$scope.capabilities); - this.$scope.filteredRequirementsList = this.$scope.sortByIsCreatedManually(this.$scope.requirements); - - this.$scope.sort = (sortBy: string, sortByTableDefined: SortTableDefined, autoCollapseCapabilitiesRows: boolean): void => { - sortByTableDefined.reverse = (sortByTableDefined.sortByField === sortBy) ? !sortByTableDefined.reverse : false; - sortByTableDefined.sortByField = sortBy; - if (autoCollapseCapabilitiesRows) { - this.$scope.allCapabilitiesSelected(false); - } - }; - - this.$scope.updateProperty = (property:PropertyModel, indexInFilteredProperties:number):void => { - this.openEditPropertyModal(property, indexInFilteredProperties); - }; - - this.$scope.allCapabilitiesSelected = (selected:boolean):void => { - _.forEach(this.$scope.capabilities, (cap:Capability)=> { - cap.selected = selected; - }); - }; - this.$scope.onAddBtnClicked = (): void => { - switch (this.$scope.mode) { - case 'requirements': - this.openRequirementsModal(); - break; - case 'capabilities': - this.openCapabilitiesModal(); - break; - } - }; - this.$scope.onEditRequirement = (req: RequirementUI): void => { - this.openRequirementsModal(req); - }; - this.$scope.onEditCapability = (cap: CapabilityUI): void => { - this.openCapabilitiesModal(cap); - }; - this.$scope.onDeleteReq = (event: Event, req: RequirementUI): void => { - event.stopPropagation(); - this.ModalServiceSdcUI.openAlertModal('Delete Requirement', - `Are you sure you want to delete requirement: ${req.name}?`, 'OK', () => this.deleteRequirement(req), 'Cancel'); - }; - this.$scope.onDeleteCap = (event: Event, cap: CapabilityUI): void => { - event.stopPropagation(); - this.ModalServiceSdcUI.openAlertModal('Delete Capability', - `Are you sure you want to delete capability: ${cap.name}?`, 'OK', () => this.deleteCapability(cap), 'Cancel'); - }; - this.$scope.onSearchIconClick = (): void => { - this.$scope.filter.show = !!this.$scope.filter.txt || !this.$scope.filter.show; - }; - this.$scope.onFilter = (): void => { - switch (this.$scope.mode) { - case 'requirements': - this.$scope.filteredRequirementsList = _.filter(this.$scope.requirements, req => req.name.includes(this.$scope.filter.txt)); - break; - case 'capabilities': - this.$scope.filteredCapabilitiesList = _.filter(this.$scope.capabilities, cap => cap.name.includes(this.$scope.filter.txt)); - break; - } - }; - this.$scope.isListEmpty = (): boolean => { - switch (this.$scope.mode) { - case 'requirements': - return this.$scope.requirements.length === 0; - case 'capabilities': - return this.$scope.capabilities.length === 0; - } - }; - this.$scope.onSwitchTab = (): void => { - this.$scope.mode = this.$scope.mode === 'requirements' ? 'capabilities' : 'requirements'; - this.$scope.filter.txt = ''; - this.$scope.filter.show = false; - this.$scope.filteredRequirementsList = this.$scope.requirements; - this.$scope.filteredCapabilitiesList = this.$scope.capabilities; - }; - this.$scope.cutToscaTypePrefix = (valToCut: string, textToStartCut: string): string => { - let index = valToCut.indexOf(textToStartCut); - return index !== -1 ? valToCut.substr(index + textToStartCut.length) : valToCut; - }; - }; - - private getIsEditableByComponentType() { - if (this.$scope.componentType === ComponentType.SERVICE) { - return true; - } - if (this.$scope.component.isResource()) { - let componentAsResource: Resource = this.$scope.component; - return componentAsResource.resourceType === ResourceType.VF || - componentAsResource.resourceType === ResourceType.PNF; - } - return false; - }; - - private fetchCapabilitiesRelatedData() { - if (this.$scope.isEditable) { - this.$scope.capabilityTypesList = []; - this.ToscaTypesServiceNg2.fetchCapabilityTypes().subscribe((result: CapabilityTypesMap) => { - _.forEach(result, capabilityType => this.$scope.capabilityTypesList.push(capabilityType)); - }); - this.$scope.nodeTypesList = []; - this.ToscaTypesServiceNg2.fetchNodeTypes().subscribe((result: NodeTypesMap) => { - _.forEach(result, nodeType => this.$scope.nodeTypesList.push(nodeType)); - }); - this.$scope.relationshipTypesList = []; - this.ToscaTypesServiceNg2.fetchRelationshipTypes().subscribe((result: RelationshipTypesMap) => { - _.forEach(result, relshipType => this.$scope.relationshipTypesList.push(relshipType)); - }); - } - } - - private openRequirementsModal(req?: RequirementUI) { - let modalConfig: IModalConfig = { - size: 'md', - title: (req ? 'Update' : 'Add') + ' Requirement', - type: 'custom', - buttons: [ - { - id: 'saveButton', - text: (req ? 'Update' : 'Create'), - size: "'x-small'", - callback: () => this.createOrUpdateRequirement(), - closeModal: true - }, - {text: "Cancel", size: "'x-small'", closeModal: true}] - }; - let modalInputs = { - requirement: req, - relationshipTypesList: this.$scope.relationshipTypesList, - nodeTypesList: this.$scope.nodeTypesList, - capabilityTypesList: this.$scope.capabilityTypesList, - isReadonly: this.$scope.isViewMode() || !this.$scope.isDesigner(), - validityChangedCallback: this.getDisabled - }; - - this.ModalServiceSdcUI.openCustomModal(modalConfig, RequirementsEditorComponent, {input: modalInputs}); - } - - private openCapabilitiesModal(cap?: CapabilityUI) { - let modalConfig: IModalConfig = { - size: 'md', - title: (cap ? 'Update' : 'Add') + ' Capability', - type: 'custom', - buttons: [ - { - id: 'saveButton', - text: (cap ? 'Update' : 'Create'), - size: "'x-small'", - callback: () => this.createOrUpdateCapability(), - closeModal: true - }, - {text: "Cancel", size: "'x-small'", closeModal: true}] - }; - let modalInputs = { - capability: cap, - capabilityTypesList: this.$scope.capabilityTypesList, - isReadonly: this.$scope.isViewMode() || !this.$scope.isDesigner(), - validityChangedCallback: this.getDisabled - }; - - this.ModalServiceSdcUI.openCustomModal(modalConfig, CapabilitiesEditorComponent, {input: modalInputs}); - } - - getDisabled = (shouldEnable: boolean): void => { - let saveButton: ModalButtonComponent = this.ModalServiceSdcUI.getCurrentInstance().getButtonById('saveButton'); - saveButton.disabled = this.$scope.isViewMode() || !this.$scope.isDesigner() || !shouldEnable; - }; - - private createOrUpdateRequirement() { - let requirement = this.ModalServiceSdcUI.getCurrentInstance().innerModalContent.instance.requirementData; - this.$scope.isLoading = true; - if (!requirement.uniqueId) { - this.ComponentServiceNg2.createRequirement(this.$scope.component, requirement).subscribe(result => { - this.$scope.requirements.unshift(new RequirementUI(result[0], this.$scope.component.uniqueId)); - this.$scope.isLoading = false; - }, () => { - this.$scope.isLoading = false; - }); - } - else { - this.ComponentServiceNg2.updateRequirement(this.$scope.component, requirement).subscribe(result => { - let index = this.$scope.requirements.findIndex(req => result[0].uniqueId === req.uniqueId); - this.$scope.requirements[index] = new RequirementUI(result[0], this.$scope.component.uniqueId); - this.$scope.isLoading = false; - this.$scope.$apply(); - }, () => { - this.$scope.isLoading = false; - }); - } - } - - private createOrUpdateCapability() { - let capability = this.ModalServiceSdcUI.getCurrentInstance().innerModalContent.instance.capabilityData; - this.$scope.isLoading = true; - if (!capability.uniqueId) { - this.ComponentServiceNg2.createCapability(this.$scope.component, capability).subscribe(result => { - this.$scope.capabilities.unshift(new CapabilityUI(result[0], this.$scope.component.uniqueId)); - this.$scope.isLoading = false; - }, () => { - this.$scope.isLoading = false; - }); - } - else { - this.ComponentServiceNg2.updateCapability(this.$scope.component, capability).subscribe(result => { - let index = this.$scope.capabilities.findIndex(cap => result[0].uniqueId === cap.uniqueId); - this.$scope.capabilities[index] = new CapabilityUI(result[0], this.$scope.component.uniqueId); - this.$scope.isLoading = false; - this.$scope.$apply(); - }, () => { - this.$scope.isLoading = false; - }); - } - } - - private deleteRequirement(req) { - this.$scope.isLoading = true; - this.ComponentServiceNg2.deleteRequirement(this.$scope.component, req.uniqueId).subscribe(() => { - this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.$scope.componentType, this.$scope.component.uniqueId).subscribe(response => { - this.$scope.component.requirements = response.requirements; - this.initScope('requirements'); - this.$scope.isLoading = false; - }, () => { - this.$scope.isLoading = false; - }); - }, () => { - this.$scope.isLoading = false; - }); - } - - private deleteCapability(cap) { - this.$scope.isLoading = true; - this.ComponentServiceNg2.deleteCapability(this.$scope.component, cap.uniqueId).subscribe(() => { - this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.$scope.componentType, this.$scope.component.uniqueId).subscribe(response => { - this.$scope.component.capabilities = response.capabilities; - this.initScope('capabilities'); - this.$scope.isLoading = false; - }, () => { - this.$scope.isLoading = false; - }); - }, () => { - this.$scope.isLoading = false; - }); - } -} - diff --git a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view.html b/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view.html deleted file mode 100644 index c661afe0ba..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view.html +++ /dev/null @@ -1,159 +0,0 @@ - - -
    -
    - - -
    -
    - - -
    - -
    -
    -
    -
    {{header.title}} - -
    -
    - -
    - -
    - There are no requirements to display - -
    -
    - -
    - {{req.name}} -
    -
    - {{req.capability.substring("tosca.capabilities.".length)}} -
    -
    - {{req.node.substring("tosca.nodes.".length)}} -
    -
    - {{req.relationship.substring("tosca.relationships.".length)}} -
    -
    -
    - {{req.minOccurrences}},{{req.maxOccurrences}} -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    {{header.title}} - -
    -
    - -
    - -
    - There are no capabilities to display - -
    -
    - -
    - - {{capability.name}} -
    -
    - {{capability.type.replace("tosca.capabilities.","")}} -
    - -
    - {{capability.description}} -
    - -
    - {{capability.validSourceTypes.join(',')}} -
    - -
    - {{capability.minOccurrences}},{{capability.maxOccurrences}} -
    -
    -
    -

    Properties

    -
    -
    -
    -
    {{header.title}} - -
    -
    - -
    -
    - There are no properties to display -
    -
    - - - -
    -
    -
    -
    -
    - -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - diff --git a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities.less b/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities.less deleted file mode 100644 index 928f6719c6..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities.less +++ /dev/null @@ -1,418 +0,0 @@ -.workspace-req-and-cap { - - width: 93%; - display: inline-block; - - .tabs{ - float: left; - position: relative; - top: 6px; - button{ - float: left; - width: 233px; - height: 38px; - background-color: @tlv_color_t; - border: 1px solid @main_color_o; - color: black; - &:nth-child(1){ - border-radius: 10px 0 0 0; - } - &:nth-child(2){ - border-radius: 0 10px 0 0; - } - &.selected{ - background-color: @main_color_a; - border: 1px solid @main_color_a; - color: white; - } - } - } - .search{ - margin-bottom: 12px; - float: right; - ::-webkit-input-placeholder { - font-style: italic; - } - :-moz-placeholder { - font-style: italic; - } - ::-moz-placeholder { - font-style: italic; - } - :-ms-input-placeholder { - font-style: italic; - } - #search-box{ - -webkit-border-radius: 2px 0 0 2px; - -moz-border-radius: 2px 0 0 2px; - border-radius: 2px 0 0 2px; - width: 213px; - height: 32px; - line-height: 32px; - border: 1px solid @main_color_o; - text-indent: 10px; - float: left; - } - .search-icon-container{ - background-color: @main_color_a; - height: 32px; - width: 32px; - border-radius: 0 2px 2px 0; - float: left; - .search-icon{ - position: relative; - top: 9px; - } - } - } - .add-button { - color: @main_color_a; - } - .add-button, .expand-collapse-buttons { - float: right; - margin-left: 11px; - margin-top: 10px; - &, span { - .hand; - } - } - - - - .table{ - height:490px; - margin-bottom: 0; - } - - .arrow-up-small{ - &.opened{ - .arrow-up-small-hover; - } - } - - .item-opened{ - background-color: @tlv_color_t; - } - - .properties-title{ - margin:0; - font-weight: bold; - } - - .table-container-flex { - margin-top: 10px; - - .text{ - overflow: hidden; - text-overflow: ellipsis; - display: inline-block; - white-space: nowrap; - } - - .editable-table-data { - max-height: 430px; - } - - .data-row { - &:not(.editable-row) { - background: @tlv_color_t; - color: @main_color_n; - } - &.editable-row { - cursor: pointer; - } - .sprite-new.delete-icon { - visibility: hidden; - } - &:hover { - .sprite-new.delete-icon { - visibility: visible; - } - } - } - - &.requirements-table{ - border-top: 4px solid @main_color_a; - .flex-item:nth-child(1) { - flex-grow: 20; - } - - .flex-item:nth-child(2) { - flex-grow: 20; - } - - .flex-item:nth-child(3) { - flex-grow: 20; - } - - .flex-item:nth-child(4) { - flex-grow: 20; - } - - .flex-item:nth-child(5) { - flex-grow: 20; - } - - .flex-item:nth-child(6) { - flex-grow: 20; - } - } - - &.capabilities-table{ - border-top: 4px solid @main_color_a; - .selected{ - .flex-item:nth-child(1) { - border-left: 4px solid @main_color_a; - padding-right: 11px; - } - } - .flex-item:nth-child(1) { - flex-grow: 10; - } - - .flex-item:nth-child(2) { - flex-grow: 10; - } - - .flex-item:nth-child(3) { - flex-grow: 10; - } - - .flex-item:nth-child(4) { - flex-grow: 10; - } - - .flex-item:nth-child(5) { - flex-grow: 10; - } - - } - - &.properties-table{ - .table{ - height: auto; - } - - .flex-item:nth-child(1) { - flex-grow: 15; - a{ - .hand - } - } - - .flex-item:nth-child(2) { - flex-grow: 6; - } - - .flex-item:nth-child(3) { - flex-grow: 6; - } - - .flex-item:nth-child(4) { - flex-grow: 20; - - } - } - - } - -} - -.workspace-req-and-cap-editable { - .tabs-header { - display: flex; - justify-content: space-between; - border-bottom: 1px solid @main_color_o; - .req-and-cap-tabs { - display: flex; - .tab { - font-family: @font-opensans-regular; - font-size: 22px; - padding: 5px; - .hand; - &:first-of-type { - margin-right: 35px; - } - &.selected { - color: @main_color_a; - border-bottom: 2px solid @main_color_a; - } - } - } - .buttons-in-right { - display: flex; - .search { - display: flex; - height: min-content; - margin-top: 10px; - padding-right: 11px; - border-right: 1px solid @main_color_o; - #search-box { - border: none; - border-bottom: 1px solid @main_color_o; - text-indent: 10px; - &:focus { - outline: none; - } - } - .search-icon-container { - margin-top: 3px; - padding-top: 4px; - } - - } - .add-button-icon-and-label { - font-size: 14px; - margin-left: 11px; - margin-top: 10px; - padding-top: 5px; - /deep/ svg-icon { - vertical-align: bottom; - } - &:hover { - &:not(.disabled) { - cursor: pointer; - color: @sdcui_color_light-blue; - } - } - } - } - } - .add-button-icon-and-label { - .icon-label-txt { - text-transform: uppercase; - font-family: @font-opensans-medium; - color: @main_color_a; - &:hover { - &:not(.disabled) { - color: @sdcui_color_light-blue; - } - } - } - } - .empty-list-container { - width: 100%; - display: flex; - justify-content: center; - - .empty-list-add-btn { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - border: 1px solid @main_color_o; - margin-top: 50px; - height: 229px; - width: 480px; - &.disabled { - pointer-events: none; - } - &:hover { - &:not(.disabled) { - border: 1px solid @main_color_a; - cursor: pointer; - } - } - .icon-label-txt { - margin-top: 15px; - font-size: 16px; - } - } - } - .table-container-flex .table { - .head .head-row { - text-align: left; - &.description { - flex: 2; - } - &.other { - flex: 0.25; - text-align: center; - } - &.occurrences { - flex: 0.75; - } - } - .body .data-row { - border-bottom: none; - border-top: @main_color_o solid 1px; - .ellipsis-text { - overflow: hidden; - text-overflow: ellipsis; - } - &:not(.editable-row) { - background-color: @tlv_color_t; - cursor: default; - color: @main_color_n; - } - &.editable-row { - cursor: pointer; - .table-col-general:hover { - color: @main_color_b; - } - } - &.selected { - background-color: @tlv_color_v; - .name-col { - color: @main_color_a; - } - .sprite-new.arrow-up-small { - background-position: -858px -137px; - margin-bottom: 2px; - } - } - .description-col { - flex: 2; - } - .occurrences-col { - flex: 0.75; - } - .other-col { - display: flex; - justify-content: center; - align-items: center; - flex: 0.25; - .trash-icon { - visibility: hidden; - } - } - &:hover { - .trash-icon { - visibility: visible; - } - } - .multiline-ellipsis { - line-height: 1.5em; - padding: 1px 0 1px 0; - /deep/ .ellipsis-directive-more-less { - float: none; - margin-left: 5px; - color: @main_color_a; - } - } - } - } - - .item-opened.properties-section { - border: 4px solid @tlv_color_v !important; - max-height: 263px; - overflow: auto; - .properties-title { - .s_10; - margin-top: 10px; - } - .properties-table { - &.table-container-flex { - margin-top: 18px; - } - .table { - .head { - border-bottom: 1px solid @main_color_o; - } - .head, .table-col-general { - background-color: @main_color_p; - } - } - } - } -} \ No newline at end of file diff --git a/catalog-ui/src/app/view-models/workspace/tabs/tosca-artifacts/tosca-artifacts-view-model.ts b/catalog-ui/src/app/view-models/workspace/tabs/tosca-artifacts/tosca-artifacts-view-model.ts deleted file mode 100644 index a1f8152cea..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/tosca-artifacts/tosca-artifacts-view-model.ts +++ /dev/null @@ -1,105 +0,0 @@ -/*- - * ============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========================================================= - */ - -'use strict'; -import * as _ from "lodash"; -import {ArtifactModel, IFileDownload} from "app/models"; -import {IWorkspaceViewModelScope} from "app/view-models/workspace/workspace-view-model"; -import {ComponentGenericResponse} from "../../../../ng2/services/responses/component-generic-response"; -import {ComponentServiceNg2} from "../../../../ng2/services/component-services/component.service"; - -export interface IToscaArtifactsScope extends IWorkspaceViewModelScope { - artifacts:Array; - tableHeadersList:Array; - artifactType:string; - downloadFile:IFileDownload; - isLoading:boolean; - sortBy:string; - reverse:boolean; - - getTitle():string; - download(artifact:ArtifactModel):void; - sort(sortBy:string):void; - showNoArtifactMessage():boolean; -} - -export class ToscaArtifactsViewModel { - - static '$inject' = [ - '$scope', - '$filter', - 'ComponentServiceNg2' - ]; - - constructor(private $scope:IToscaArtifactsScope, - private $filter:ng.IFilterService, - private ComponentServiceNg2:ComponentServiceNg2) { - this.initToscaArtifacts(); - } - - private initToscaArtifacts = (): void => { - - if(!this.$scope.component.toscaArtifacts) { - this.$scope.isLoading = true; - this.ComponentServiceNg2.getComponentToscaArtifacts(this.$scope.component).subscribe((response:ComponentGenericResponse) => { - this.$scope.component.toscaArtifacts = response.toscaArtifacts; - this.initScope(); - this.$scope.isLoading = false; - }, () => { - this.$scope.isLoading = false; - }); - } else { - this.initScope(); - } - } - - private initScope = ():void => { - this.$scope.isLoading = false; - this.$scope.sortBy = 'artifactDisplayName'; - this.$scope.reverse = false; - this.$scope.setValidState(true); - this.$scope.artifactType = 'informational'; - this.$scope.getTitle = ():string => { - return this.$filter("resourceName")(this.$scope.component.name) + ' Artifacts'; - - }; - - this.$scope.tableHeadersList = [ - {title: 'Name', property: 'artifactDisplayName'}, - {title: 'Type', property: 'artifactType'}, - {title: 'Version', property: 'artifactVersion'} - ]; - - this.$scope.artifacts = _.values(this.$scope.component.toscaArtifacts); - this.$scope.sort = (sortBy:string):void => { - this.$scope.reverse = (this.$scope.sortBy === sortBy) ? !this.$scope.reverse : false; - this.$scope.sortBy = sortBy; - }; - - - this.$scope.showNoArtifactMessage = ():boolean => { - if (this.$scope.artifacts.length === 0) { - return true; - } - return false; - }; - - } -} diff --git a/catalog-ui/src/app/view-models/workspace/tabs/tosca-artifacts/tosca-artifacts-view.html b/catalog-ui/src/app/view-models/workspace/tabs/tosca-artifacts/tosca-artifacts-view.html deleted file mode 100644 index b354e7a544..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/tosca-artifacts/tosca-artifacts-view.html +++ /dev/null @@ -1,65 +0,0 @@ - - -
    -
    -
    -
    -
    {{header.title}} - -
    -
    -
    -
    - -
    - There are no TOSCA artifacts to display -
    -
    - -
    - - {{artifact.artifactDisplayName}} -
    - -
    - {{artifact.artifactType}} -
    - -
    - {{artifact.artifactVersion}} -
    - -
    - -
    -
    -
    -
    Label: {{artifact.artifactLabel}}
    -
    UUID: {{artifact.artifactUUID}}
    -
    Description: {{artifact.description}}
    - - -
    - -
    -
    -
    -
    -
    diff --git a/catalog-ui/src/app/view-models/workspace/tabs/tosca-artifacts/tosca-artifacts.less b/catalog-ui/src/app/view-models/workspace/tabs/tosca-artifacts/tosca-artifacts.less deleted file mode 100644 index 23be3c3548..0000000000 --- a/catalog-ui/src/app/view-models/workspace/tabs/tosca-artifacts/tosca-artifacts.less +++ /dev/null @@ -1,77 +0,0 @@ -.workspace-tosca-artifact { - width: 100%; - display: inline-block; - .w-sdc-classic-btn { - float: right; - margin-bottom: 10px; - } - - .details-title{ - font-weight: bold; - margin-right: 5px; - } - - .table{ - height: 490px; - margin-bottom: 0; - } - - - .table-container-flex { - margin-top: 0; - .item-opened{ - word-wrap: break-word; - } - - - .flex-item:nth-child(1) { - flex-grow: 15; - .hand; - span.table-arrow { - margin-right: 7px; - } - } - - .flex-item:nth-child(2) { - flex-grow: 6; - } - - .flex-item:nth-child(3) { - flex-grow: 1; - } - - .flex-item:nth-child(4) { - flex-grow: 1; - } - - - - - .table-download-btn{ - &.tosca{ - margin-left: 0; - margin-top: 8px; - } - } - - .download-icon-container{ - position: relative; - - .loader{ - left: 60%; - top: 45px; - border: none; - background-color: transparent; - height: 0px; - width: 63px; - outline: none; - - } - } - - - } - -} - - diff --git a/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts b/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts index f4bbed2c96..11667283b2 100644 --- a/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts +++ b/catalog-ui/src/app/view-models/workspace/workspace-view-model.ts @@ -22,103 +22,110 @@ * Created by obarda on 3/30/2016. */ 'use strict'; -import * as _ from "lodash"; +import * as _ from 'lodash'; import { - IUserProperties, IAppMenu, Resource, Component, Plugin, PluginsConfiguration, PluginDisplayOptions, - RelationshipTypeModel, NodeTypeModel, CapabilityTypeModel -} from "app/models"; + IUserProperties, + IAppMenu, + Resource, + Component, + Plugin, + PluginsConfiguration, + PluginDisplayOptions +} from 'app/models'; import { - WorkspaceMode, ComponentFactory, ChangeLifecycleStateHandler, Role, ComponentState, MenuItemGroup, MenuHandler, - MenuItem, ModalsHandler, States, EVENTS, CHANGE_COMPONENT_CSAR_VERSION_FLAG, ResourceType, PREVIOUS_CSAR_COMPONENT -} from "app/utils"; + MenuItem, ModalsHandler, States, EVENTS, CHANGE_COMPONENT_CSAR_VERSION_FLAG, ResourceType, PREVIOUS_CSAR_COMPONENT, + WorkspaceMode, ComponentFactory, ChangeLifecycleStateHandler, Role, ComponentState, MenuItemGroup, MenuHandler +} from 'app/utils'; import { EventListenerService, - EntityService, - ProgressService, - CacheService, - LeftPaletteLoaderService -} from "app/services"; -import {FileUploadModel} from "../../directives/file-upload/file-upload"; -import {AutomatedUpgradeService} from "../../ng2/pages/automated-upgrade/automated-upgrade.service"; -import {ComponentServiceNg2} from "../../ng2/services/component-services/component.service"; -import {EventBusService} from "../../ng2/services/event-bus.service"; -import {PluginsService} from "../../ng2/services/plugins.service"; -import {IDependenciesServerResponse} from "../../ng2/services/responses/dependencies-server-response"; + LeftPaletteLoaderService, + ProgressService +} from 'app/services'; +import { + CacheService +} from 'app/services-ng2'; +import { AutomatedUpgradeService } from '../../ng2/pages/automated-upgrade/automated-upgrade.service'; +import { CatalogService } from '../../ng2/services/catalog.service'; +import { ComponentServiceNg2 } from '../../ng2/services/component-services/component.service'; +import { EventBusService } from '../../ng2/services/event-bus.service'; +import { HomeService } from '../../ng2/services/home.service'; +import { PluginsService } from '../../ng2/services/plugins.service'; +import { IDependenciesServerResponse } from '../../ng2/services/responses/dependencies-server-response'; +import { WorkspaceNg1BridgeService } from '../../ng2/pages/workspace/workspace-ng1-bridge-service'; +import { WorkspaceService } from '../../ng2/pages/workspace/workspace.service'; export interface IWorkspaceViewModelScope extends ng.IScope { - isLoading:boolean; - isCreateProgress:boolean; - component:Component; - originComponent:Component; - componentType:string; - importFile:any; - leftBarTabs:MenuItemGroup; - isNew:boolean; - isFromImport:boolean; - isValidForm:boolean; - isActiveTopBar:boolean; - mode:WorkspaceMode; - breadcrumbsModel:Array; - sdcMenu:IAppMenu; - changeLifecycleStateButtons:any; - version:string; - versionsList:Array; - changeVersion:any; - isComposition:boolean; - isDeployment:boolean; - isPlugins:boolean; - $state:ng.ui.IStateService; - user:IUserProperties; - thirdParty:boolean; - disabledButtons:boolean; - menuComponentTitle:string; - progressService:ProgressService; - progressMessage:string; + isLoading: boolean; + isCreateProgress: boolean; + component: Component; + originComponent: Component; + componentType: string; + importFile: any; + leftBarTabs: MenuItemGroup; + isNew: boolean; + isFromImport: boolean; + isValidForm: boolean; + isActiveTopBar: boolean; + mode: WorkspaceMode; + breadcrumbsModel: Array; + sdcMenu: IAppMenu; + changeLifecycleStateButtons: any; + version: string; + versionsList: Array; + changeVersion: any; + isComposition: boolean; + isDeployment: boolean; + isPlugins: boolean; + $state: ng.ui.IStateService; + user: IUserProperties; + thirdParty: boolean; + disabledButtons: boolean; + menuComponentTitle: string; + progressService: ProgressService; + progressMessage: string; ComponentServiceNg2: ComponentServiceNg2; // leftPanelComponents:Array; //this is in order to load the left panel once, and not wait long time when moving to composition - unsavedChanges:boolean; - unsavedChangesCallback:Function; - unsavedFile:boolean; - capabilityTypesList: Array; - relationshipTypesList: Array; - nodeTypesList: Array; - - - startProgress(message:string):void; - stopProgress():void; - updateBreadcrumbs(component:Component):void; - updateUnsavedFileFlag(isUnsaved:boolean):void; - showChangeStateButton():boolean; - getComponent():Component; - setComponent(component:Component):void; - setOriginComponent(component:Component):void; - onMenuItemPressed(state:string, params:any):ng.IPromise; - create():void; - save():Promise; - setValidState(isValid:boolean):void; - changeLifecycleState(state:string):void; - handleChangeLifecycleState(state:string, newCsarVersion?:string):void; - disableMenuItems():void; - enableMenuItems():void; - isDesigner():boolean; - isViewMode():boolean; - isEditMode():boolean; - isCreateMode():boolean; - isDisableMode():boolean; - isGeneralView():boolean; - goToBreadcrumbHome():void; - onVersionChanged(selectedId:string):void; - getLatestVersion():void; - getStatus():string; - showLifecycleIcon():boolean; - updateSelectedMenuItem(state:string):void; - isSelected(menuItem:MenuItem):boolean; - uploadFileChangedInGeneralTab():void; - updateMenuComponentName(ComponentName:string):void; - getTabTitle():string; - reload(component:Component):void; + unsavedChanges: boolean; + unsavedChangesCallback: Function; + unsavedFile: boolean; + hasNoDependencies: boolean; + + + startProgress(message: string): void; + stopProgress(): void; + updateBreadcrumbs(component: Component): void; + updateUnsavedFileFlag(isUnsaved: boolean): void; + showChangeStateButton(): boolean; + getComponent(): Component; + setComponent(component: Component): void; + setOriginComponent(component: Component): void; + onMenuItemPressed(state: string, params: any): ng.IPromise; + create(): void; + save(): Promise; + setValidState(isValid: boolean): void; + changeLifecycleState(state: string): void; + handleChangeLifecycleState(state: string, newCsarVersion?: string, errorFunction?: Function): void; + disableMenuItems(): void; + enableMenuItems(): void; + isDesigner(): boolean; + isViewMode(): boolean; + isEditMode(): boolean; + isCreateMode(): boolean; + isDisableMode(): boolean; + isGeneralView(): boolean; + goToBreadcrumbHome(): void; + onVersionChanged(selectedId: string): void; + getLatestVersion(): void; + getStatus(): string; + showLifecycleIcon(): boolean; + updateSelectedMenuItem(state: string): void; + isSelected(menuItem: MenuItem): boolean; + uploadFileChangedInGeneralTab(): void; + updateMenuComponentName(ComponentName: string): void; + getTabTitle(): string; + reload(component: Component): void; } export class WorkspaceViewModel { @@ -133,53 +140,55 @@ export class WorkspaceViewModel { 'MenuHandler', 'Sdc.Services.CacheService', 'ChangeLifecycleStateHandler', - 'ModalsHandler', 'LeftPaletteLoaderService', '$filter', 'EventListenerService', - 'Sdc.Services.EntityService', 'Notification', '$stateParams', + 'HomeService', + 'CatalogService', 'Sdc.Services.ProgressService', 'ComponentServiceNg2', 'AutomatedUpgradeService', 'EventBusService', - 'PluginsService' + 'PluginsService', + 'WorkspaceNg1BridgeService', + 'workspaceService' ]; - constructor(private $scope:IWorkspaceViewModelScope, - private injectComponent:Component, - private ComponentFactory:ComponentFactory, - private $state:ng.ui.IStateService, - private sdcMenu:IAppMenu, - private $q:ng.IQService, - private MenuHandler:MenuHandler, - private cacheService:CacheService, - private ChangeLifecycleStateHandler:ChangeLifecycleStateHandler, - private ModalsHandler:ModalsHandler, - private LeftPaletteLoaderService:LeftPaletteLoaderService, - private $filter:ng.IFilterService, - private EventListenerService:EventListenerService, - private EntityService:EntityService, - private Notification:any, - private $stateParams:any, - private progressService:ProgressService, - private ComponentServiceNg2:ComponentServiceNg2, - private AutomatedUpgradeService:AutomatedUpgradeService, - private eventBusService:EventBusService, - private pluginsService:PluginsService) { - - - - this.initScope(); - this.initAfterScope(); - this.$scope.updateSelectedMenuItem(this.$state.current.name); + constructor(private $scope: IWorkspaceViewModelScope, + private injectComponent: Component, + private ComponentFactory: ComponentFactory, + private $state: ng.ui.IStateService, + private sdcMenu: IAppMenu, + private $q: ng.IQService, + private MenuHandler: MenuHandler, + private cacheService: CacheService, + private ChangeLifecycleStateHandler: ChangeLifecycleStateHandler, + private LeftPaletteLoaderService: LeftPaletteLoaderService, + private $filter: ng.IFilterService, + private EventListenerService: EventListenerService, + private Notification: any, + private $stateParams: any, + private homeService: HomeService, + private catalogService: CatalogService, + private progressService: ProgressService, + private ComponentServiceNg2: ComponentServiceNg2, + private AutomatedUpgradeService: AutomatedUpgradeService, + private eventBusService: EventBusService, + private pluginsService: PluginsService, + private workspaceNg1BridgeService: WorkspaceNg1BridgeService, + private workspaceService: WorkspaceService) { + + this.initScope(); + // this.initAfterScope(); + this.$scope.updateSelectedMenuItem(this.$state.current.name); } - private role:string; - private category:string; - private components:Array; - + private role: string; + private category: string; + private components: Component[]; + private initViewMode = ():WorkspaceMode => { let mode = WorkspaceMode.VIEW; @@ -187,35 +196,34 @@ export class WorkspaceViewModel { mode = WorkspaceMode.CREATE; } else { if (this.$scope.component.lifecycleState === ComponentState.NOT_CERTIFIED_CHECKOUT && - this.$scope.component.lastUpdaterUserId === this.cacheService.get("user").userId) { - if ((this.$scope.component.isService() || this.$scope.component.isResource()) && this.role == Role.DESIGNER) { + this.$scope.component.lastUpdaterUserId === this.cacheService.get('user').userId) { + if ((this.$scope.component.isService() || this.$scope.component.isResource()) && this.role === Role.DESIGNER) { mode = WorkspaceMode.EDIT; } } } + this.workspaceNg1BridgeService.updateIsViewOnly(mode === WorkspaceMode.VIEW); return mode; - }; + } - private initChangeLifecycleStateButtons = ():void => { - let state = this.$scope.component.isService() && (Role.OPS == this.role || Role.GOVERNOR == this.role) ? this.$scope.component.distributionStatus : this.$scope.component.lifecycleState; + private initChangeLifecycleStateButtons = (): void => { + let state: string; + if (this.$scope.component.isService() && this.$scope.component.lifecycleState === 'CERTIFIED') { + state = this.$scope.component.distributionStatus; + } else { + state = this.$scope.component.lifecycleState; + } this.$scope.changeLifecycleStateButtons = (this.sdcMenu.roles[this.role].changeLifecycleStateButtons[state] || [])[this.$scope.component.componentType.toUpperCase()]; + } - }; - - private initLeftPalette = ():void => { - //this.LeftPaletteLoaderService.loadLeftPanel(this.$scope.component); - }; - - private initScope = ():void => { - + private initScope = (): void => { this.$scope.component = this.injectComponent; - //this.initLeftPalette(); this.$scope.menuComponentTitle = this.$scope.component.name; this.$scope.disabledButtons = false; this.$scope.originComponent = this.ComponentFactory.createComponent(this.$scope.component); this.$scope.componentType = this.$scope.component.componentType; this.$scope.version = this.cacheService.get('version'); - this.$scope.user = this.cacheService.get("user"); + this.$scope.user = this.cacheService.get('user'); this.role = this.$scope.user.role; this.category = this.$scope.component.selectedCategory; this.$scope.mode = this.initViewMode(); @@ -229,10 +237,11 @@ export class WorkspaceViewModel { this.$scope.progressService = this.progressService; this.$scope.unsavedChanges = false; - this.EventListenerService.registerObserverCallback(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.setWorkspaceButtonState); - //this.EventListenerService.registerObserverCallback(EVENTS.ON_UPDATE_VSP_FILE, this.updateVspFlag); + this.$scope.hasNoDependencies = true; + this.verifyIfDependenciesExist(); - this.$scope.getComponent = ():Component => { + this.EventListenerService.registerObserverCallback(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.setWorkspaceButtonState); + this.$scope.getComponent = (): Component => { return this.$scope.component; }; @@ -261,17 +270,17 @@ export class WorkspaceViewModel { this.$scope.archiveComponent = ():void => { this.$scope.isLoading = true; const typeComponent = this.$scope.component.componentType; - this.ComponentServiceNg2.archiveComponent(typeComponent, this.$scope.component.uniqueId).subscribe(()=>{ + this.ComponentServiceNg2.archiveComponent(typeComponent, this.$scope.component.uniqueId).subscribe(()=> { this.$scope.isLoading = false; - if(this.$state.params.previousState){ - switch(this.$state.params.previousState){ + if (this.$state.params.previousState) { + switch (this.$state.params.previousState) { case 'catalog': case 'dashboard': this.$state.go(this.$state.params.previousState); break; default: break; - } + } } this.$scope.component.archived = true; this.deleteArchiveCache(); @@ -281,17 +290,17 @@ export class WorkspaceViewModel { title: this.$filter('translate')("ARCHIVE_SUCCESS_MESSAGE_TITLE") }); }, (error) => { this.$scope.isLoading = false; }); - } + } this.$scope.restoreComponent = ():void => { this.$scope.isLoading = true; const typeComponent = this.$scope.component.componentType; - this.ComponentServiceNg2.restoreComponent(typeComponent, this.$scope.component.uniqueId).subscribe(()=>{ + this.ComponentServiceNg2.restoreComponent(typeComponent, this.$scope.component.uniqueId).subscribe(()=> { this.$scope.isLoading = false; this.Notification.success({ - message: this.$scope.component.name + ' ' + this.$filter('translate')("RESTORE_SUCCESS_MESSAGE_TEXT"), - title: this.$filter('translate')("RESTORE_SUCCESS_MESSAGE_TITLE") - }); + message: this.$scope.component.name + ' ' + this.$filter('translate')("RESTORE_SUCCESS_MESSAGE_TEXT"), + title: this.$filter('translate')("RESTORE_SUCCESS_MESSAGE_TITLE") + }); }); this.$scope.component.archived = false; this.deleteArchiveCache(); @@ -304,13 +313,13 @@ export class WorkspaceViewModel { if(this.$scope.isValidForm){ this.$scope.save().then(() => { this.$scope.onMenuItemPressed(toState.name, toParams); - }, ()=> { + }, ()=> { console.error("Save failed, unable to navigate to " + toState.name); }) } else { console.error("Form is invalid, unable to navigate to " + toState.name); } - } + } } }); @@ -384,7 +393,7 @@ export class WorkspaceViewModel { }; this.$scope.create = () => { - + this.$scope.startProgress("Creating Asset..."); _.first(this.$scope.leftBarTabs.menuItems).isDisabled = true;//disabled click on general tab (DE246274) @@ -429,7 +438,7 @@ export class WorkspaceViewModel { }; this.$scope.save = ():Promise => { - + this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_CLICK); this.$scope.startProgress("Updating Asset..."); @@ -445,6 +454,7 @@ export class WorkspaceViewModel { let onFailed = () => { stopProgressAndEnableUI(); + this.$scope.updateUnsavedFileFlag(true); this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_SAVE_BUTTON_ERROR); reject(); @@ -459,7 +469,7 @@ export class WorkspaceViewModel { }); this.$scope.updateBreadcrumbs(component); - + //update the component this.$scope.setComponent(component); this.$scope.originComponent = this.ComponentFactory.createComponent(this.$scope.component); @@ -467,13 +477,14 @@ export class WorkspaceViewModel { if (this.cacheService.contains(CHANGE_COMPONENT_CSAR_VERSION_FLAG)) { this.cacheService.remove(CHANGE_COMPONENT_CSAR_VERSION_FLAG); } - if (this.cacheService.contains(PREVIOUS_CSAR_COMPONENT)){ + if (this.cacheService.contains(PREVIOUS_CSAR_COMPONENT)) { this.cacheService.remove(PREVIOUS_CSAR_COMPONENT); } //clear edit flags this.$state.current.data.unsavedChanges = false; this.$scope.unsavedFile = false; + this.$scope.reload(component); resolve(); }; @@ -497,35 +508,40 @@ export class WorkspaceViewModel { this.$state.go('dashboard'); }; - this.$scope.handleChangeLifecycleState = (state:string, newCsarVersion?:string) => { + this.$scope.handleChangeLifecycleState = (state:string, newCsarVersion?:string, onError?: Function) => { if ('monitor' === state) { this.$state.go('workspace.distribution'); return; } let data = this.$scope.changeLifecycleStateButtons[state]; - let onSuccess = (component:Component, url:string):void => { - //Updating the component from server response - + if (!data && this.$stateParams.componentCsar && !this.$scope.isCreateMode()) { + data = {text: 'Check Out', url: 'lifecycleState/CHECKOUT'}; + } + const onSuccess = (component, url:string):void => { + // Updating the component from server response + // Creating the data object to notify the plugins with - let eventData: any = { + const eventData: any = { uuid: this.$scope.component.uuid, version: this.$scope.component.version }; - //the server returns only metaData (small component) except checkout (Full component) ,so we update only the statuses of distribution & lifecycle + // the server returns only metaData (small component) except checkout (Full component) ,so we update only the statuses of distribution & lifecycle this.$scope.component.lifecycleState = component.lifecycleState; this.$scope.component.distributionStatus = component.distributionStatus; switch (url) { case 'lifecycleState/CHECKOUT': + this.workspaceNg1BridgeService.updateIsViewOnly(false); this.eventBusService.notify("CHECK_OUT", eventData, false).subscribe(() => { // only checkOut get the full component from server // this.$scope.component = component; // Work around to change the csar version if(newCsarVersion) { this.cacheService.set(CHANGE_COMPONENT_CSAR_VERSION_FLAG, newCsarVersion); - } + (this.$scope.component as Resource).csarVersion = newCsarVersion; + } //when checking out a minor version uuid remains const bcIdx = _.findIndex(this.components, (item) => { @@ -542,6 +558,7 @@ export class WorkspaceViewModel { this.initVersionObject(); this.$scope.isLoading = false; this.EventListenerService.notifyObservers(EVENTS.ON_CHECKOUT, component); + this.workspaceService.setComponentMetadata(component); this.Notification.success({ message: this.$filter('translate')("CHECKOUT_SUCCESS_MESSAGE_TEXT"), @@ -551,6 +568,7 @@ export class WorkspaceViewModel { }); break; case 'lifecycleState/CHECKIN': + this.workspaceNg1BridgeService.updateIsViewOnly(true); defaultActionAfterChangeLifecycleState(); this.Notification.success({ message: this.$filter('translate')("CHECKIN_SUCCESS_MESSAGE_TEXT"), @@ -566,77 +584,25 @@ export class WorkspaceViewModel { }); }); break; - case 'lifecycleState/certificationRequest': - defaultActionAfterChangeLifecycleState(); - this.Notification.success({ - message: this.$filter('translate')("SUBMIT_FOR_TESTING_SUCCESS_MESSAGE_TEXT"), - title: this.$filter('translate')("SUBMIT_FOR_TESTING_SUCCESS_MESSAGE_TITLE") - }); - break; - //Tester Role - case 'lifecycleState/failCertification': - defaultActionAfterChangeLifecycleState(); - this.Notification.success({ - message: this.$filter('translate')("REJECT_SUCCESS_MESSAGE_TEXT"), - title: this.$filter('translate')("REJECT_SUCCESS_MESSAGE_TITLE") - }); - break; case 'lifecycleState/certify': - this.$scope.handleCertification(component); - + this.verifyIfDependenciesExist(); + this.$scope.reload(component); break; - //DE203504 Bug Fix Start - case 'lifecycleState/startCertification': - this.initChangeLifecycleStateButtons(); - this.Notification.success({ - message: this.$filter('translate')("START_TESTING_SUCCESS_MESSAGE_TEXT"), - title: this.$filter('translate')("START_TESTING_SUCCESS_MESSAGE_TITLE") - }); - break; - case 'lifecycleState/cancelCertification': - this.initChangeLifecycleStateButtons(); - this.Notification.success({ - message: this.$filter('translate')("CANCEL_TESTING_SUCCESS_MESSAGE_TEXT"), - title: this.$filter('translate')("CANCEL_TESTING_SUCCESS_MESSAGE_TITLE") - }); - break; - //Ops Role - case 'distribution/PROD/activate': - this.initChangeLifecycleStateButtons(); + case 'distribution/PROD/activate': this.Notification.success({ message: this.$filter('translate')("DISTRIBUTE_SUCCESS_MESSAGE_TEXT"), title: this.$filter('translate')("DISTRIBUTE_SUCCESS_MESSAGE_TITLE") }); - break; - //Governor Role - case 'distribution-state/reject': this.initChangeLifecycleStateButtons(); - this.Notification.success({ - message: this.$filter('translate')("REJECT_SUCCESS_MESSAGE_TEXT"), - title: this.$filter('translate')("REJECT_SUCCESS_MESSAGE_TITLE") - }); break; - case 'distribution-state/approve': - this.initChangeLifecycleStateButtons(); - this.$state.go('catalog'); - this.Notification.success({ - message: this.$filter('translate')("APPROVE_SUCCESS_MESSAGE_TEXT"), - title: this.$filter('translate')("APPROVE_SUCCESS_MESSAGE_TITLE") - }); - break; - //DE203504 Bug Fix End - default : defaultActionAfterChangeLifecycleState(); - } - if (data.url != 'lifecycleState/CHECKOUT') { + if (data.url !== 'lifecycleState/CHECKOUT') { this.$scope.isLoading = false; } }; - //this.$scope.isLoading = true; - this.ChangeLifecycleStateHandler.changeLifecycleState(this.$scope.component, data, this.$scope, onSuccess); }; @@ -663,6 +629,21 @@ export class WorkspaceViewModel { return this.$scope.mode === WorkspaceMode.CREATE; }; + this.$scope.checkDisableButton = (button: any):boolean => { + // Logic moved from html to component + if (this.$scope.isCreateMode() || button.disabled || this.$scope.disabledButtons || !this.$scope.isValidForm || this.$scope.unsavedChanges || this.$scope.component.archived){ + return true; + } + + // Specific verification for Checkout - enabled only in case the component is the latest version. + let result: boolean = false; + + if (button.url === 'lifecycleState/CHECKOUT') { + result = !this.$scope.component.isLatestVersion(); + } + return result; + }; + this.$scope.isEditMode = ():boolean => { return this.$scope.mode === WorkspaceMode.EDIT; }; @@ -686,18 +667,14 @@ export class WorkspaceViewModel { this.initMenuItems(); - this.$scope.showChangeStateButton = ():boolean => { - let result:boolean = true; - if (!this.$scope.component.isLatestVersion() && Role.OPS != this.role && Role.GOVERNOR != this.role) { + this.$scope.showLatestVersion = (): boolean => { + let result: boolean = true; + if (!this.$scope.component.isLatestVersion()) { result = false; } if (ComponentState.NOT_CERTIFIED_CHECKOUT === this.$scope.component.lifecycleState && this.$scope.isViewMode()) { result = false; } - if (ComponentState.CERTIFIED != this.$scope.component.lifecycleState && - (Role.OPS == this.role || Role.GOVERNOR == this.role)) { - result = false; - } return result; }; @@ -705,20 +682,20 @@ export class WorkspaceViewModel { let stateArray:Array = state.split('.', 2); let stateWithoutInternalNavigate:string = stateArray[0] + '.' + stateArray[1]; let selectedItem:MenuItem = _.find(this.$scope.leftBarTabs.menuItems, (item:MenuItem) => { - let itemStateArray: Array = item.state.split('.', 2); + let itemStateArray:Array = item.state.split('.', 2); let itemStateWithoutNavigation:string = itemStateArray[0] + '.' + itemStateArray[1]; return (itemStateWithoutNavigation === stateWithoutInternalNavigate); }); let selectedIndex = selectedItem ? this.$scope.leftBarTabs.menuItems.indexOf(selectedItem) : 0; - if (stateArray[1] === 'plugins') { + if (stateArray[1] === 'plugins') { _.forEach(PluginsConfiguration.plugins, (plugin) => { if (plugin.pluginStateUrl == this.$state.params.path) { return false; } else if (this.pluginsService.isPluginDisplayedInContext(plugin, this.role, this.$scope.component.getComponentSubType())) { - selectedIndex++; + selectedIndex++; } }); } @@ -726,11 +703,11 @@ export class WorkspaceViewModel { this.$scope.leftBarTabs.selectedIndex = selectedIndex; }; - this.$scope.isSelected = (menuItem:MenuItem): boolean => { + this.$scope.isSelected = (menuItem: MenuItem): boolean => { return this.$scope.leftBarTabs.selectedIndex === _.indexOf(this.$scope.leftBarTabs.menuItems, menuItem); }; - this.$scope.$watch('$state.current.name', (newVal:string):void => { + this.$scope.$watch('$state.current.name', (newVal: string): void => { if (newVal) { this.$scope.isComposition = (newVal.indexOf(States.WORKSPACE_COMPOSITION) > -1); this.$scope.isDeployment = newVal == States.WORKSPACE_DEPLOYMENT; @@ -738,20 +715,26 @@ export class WorkspaceViewModel { } }); - this.$scope.getTabTitle = ():string => { - return this.$scope.leftBarTabs.menuItems.find((menuItem:MenuItem) => { + this.$scope.getTabTitle = (): string => { + return this.$scope.leftBarTabs.menuItems.find((menuItem: MenuItem) => { return menuItem.state == this.$scope.$state.current.name; }).text; }; - this.$scope.reload = (component:Component):void => { - this.$state.go(this.$state.current.name, {id: component.uniqueId}, {reload: true}); + this.$scope.reload = (component: Component): void => { + const isGeneralTab = this.$state.current.name === 'workspace.general'; + // nullify the componentCsar in case we are in general tab so we know we didnt came from updateVsp Modal + if (isGeneralTab) { + this.$state.go(this.$state.current.name, {id: component.uniqueId, componentCsar: null}, {reload: true}); + } else { + this.$state.go(this.$state.current.name, {id: component.uniqueId}, {reload: true}); + } }; this.$scope.$on('$destroy', () => { this.EventListenerService.unRegisterObserver(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES); }); - + this.$scope.openAutomatedUpgradeModal = ():void => { this.$scope.isLoading = true; this.ComponentServiceNg2.getDependencies(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response:Array)=> { @@ -761,14 +744,14 @@ export class WorkspaceViewModel { } this.$scope.handleCertification = (certifyComponent): void => { - if (this.$scope.component.getComponentSubType() === ResourceType.VF) { + if (this.$scope.component.getComponentSubType() === ResourceType.VF || this.$scope.component.isService()) { this.ComponentServiceNg2.getDependencies(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response:Array) => { this.$scope.isLoading = false; - let isUpgradeNeeded = _.filter(response, (componentToUpgrade:IDependenciesServerResponse) => { + const isUpgradeNeeded = _.filter(response, (componentToUpgrade:IDependenciesServerResponse) => { return componentToUpgrade.dependencies && componentToUpgrade.dependencies.length > 0; }); - if(isUpgradeNeeded.length === 0) { + if (isUpgradeNeeded.length === 0) { this.onSuccessWithoutUpgradeNeeded(); return; } @@ -781,52 +764,54 @@ export class WorkspaceViewModel { } this.$scope.disableMenuItems = () => { - this.$scope.leftBarTabs.menuItems.forEach((item:MenuItem) => { - item.isDisabled = (States.WORKSPACE_GENERAL != item.state); + this.$scope.leftBarTabs.menuItems.forEach((item: MenuItem) => { + item.isDisabled = (States.WORKSPACE_GENERAL !== item.state); }); } - + this.$scope.enableMenuItems = () => { - this.$scope.leftBarTabs.menuItems.forEach((item:MenuItem) => { + this.$scope.leftBarTabs.menuItems.forEach((item: MenuItem) => { item.isDisabled = false; }); - } + }; - this.$scope.startProgress = (message:string):void => { + this.$scope.startProgress = (message: string): void => { this.progressService.initCreateComponentProgress(this.$scope.component.uniqueId); this.$scope.isCreateProgress = true; this.$scope.progressMessage = message; }; - this.$scope.stopProgress = ():void => { + this.$scope.stopProgress = (): void => { this.$scope.isCreateProgress = false; this.progressService.deleteProgressValue(this.$scope.component.uniqueId); } - this.$scope.updateBreadcrumbs = (component:Component):void => { + this.$scope.updateBreadcrumbs = (component: Component): void => { // Update the components list for breadcrumbs const bcIdx = this.MenuHandler.findBreadcrumbComponentIndex(this.components, component); if (bcIdx !== -1) { this.components[bcIdx] = component; this.initBreadcrumbs(); // re-calculate breadcrumbs } - } + }; this.$scope.updateUnsavedFileFlag = (isUnsaved:boolean) => { this.$scope.unsavedFile = isUnsaved; - } + }; - }; + } - private onSuccessWithoutUpgradeNeeded = ():void => { + private onSuccessWithoutUpgradeNeeded = (): void => { this.$scope.isLoading = false; this.Notification.success({ - message: this.$filter('translate')("ACCEPT_TESTING_SUCCESS_MESSAGE_TEXT"), - title: this.$filter('translate')("ACCEPT_TESTING_SUCCESS_MESSAGE_TITLE") + message: this.$filter('translate')('SERVICE_CERTIFICATION_STATUS_TEXT'), + title: this.$filter('translate')('SERVICE_CERTIFICATION_STATUS_TITLE') }); - this.$state.go('dashboard'); + this.initVersionObject(); + this.initChangeLifecycleStateButtons(); } + private refreshDataAfterChangeLifecycleState = (component:Component):void => { this.$scope.isLoading = false; this.$scope.mode = this.initViewMode(); @@ -835,42 +820,42 @@ export class WorkspaceViewModel { this.EventListenerService.notifyObservers(EVENTS.ON_LIFECYCLE_CHANGE, component); } - private initAfterScope = ():void => { + private initAfterScope = (): void => { // In case user select csar from the onboarding modal, need to disable checkout and submit for testing. if (this.$state.params['disableButtons'] === true) { this.$scope.uploadFileChangedInGeneralTab(); } }; - private initVersionObject = ():void => { + private initVersionObject = (): void => { this.$scope.versionsList = (this.$scope.component.getAllVersionsAsSortedArray()).reverse(); this.$scope.changeVersion = { - selectedVersion: _.find(this.$scope.versionsList, (versionObj)=> { + selectedVersion: _.find(this.$scope.versionsList, (versionObj) => { return versionObj.versionId === this.$scope.component.uniqueId; }) }; - }; + } - private getNewComponentBreadcrumbItem = ():MenuItem => { - let text = ""; + private getNewComponentBreadcrumbItem = (): MenuItem => { + let text = ''; if (this.$scope.component.isResource() && (this.$scope.component).isCsarComponent()) { text = this.$scope.component.getComponentSubType() + ': ' + this.$scope.component.name; } else { text = 'Create new ' + this.$state.params['type']; } return new MenuItem(text, null, States.WORKSPACE_GENERAL, 'goToState', [this.$state.params]); - }; + } - private updateMenuItemByRole = (menuItems:Array, role:string) => { - let tempMenuItems:Array = new Array(); - menuItems.forEach((item:any) => { + private updateMenuItemByRole = (menuItems: any[], role: string) => { + const tempMenuItems: any[] = new Array(); + menuItems.forEach((item: any) => { //remove item if role is disabled if (!(item.disabledRoles && item.disabledRoles.indexOf(role) > -1)) { tempMenuItems.push(item); } }); return tempMenuItems; - }; + } private updateMenuItemByCategory = (menuItems:Array, category:string) => { let tempMenuItems:Array = new Array(); @@ -888,15 +873,15 @@ export class WorkspaceViewModel { private deleteArchiveCache = () => { - this.cacheService.remove("archiveComponents"); //delete the cache to ensure the archive is reloaded from server - }; + this.cacheService.remove('archiveComponents'); // delete the cache to ensure the archive is reloaded from server + } private initBreadcrumbs = () => { this.components = this.cacheService.get('breadcrumbsComponents'); - let breadcrumbsComponentsLvl = this.MenuHandler.generateBreadcrumbsModelFromComponents(this.components, this.$scope.component); + const breadcrumbsComponentsLvl = this.MenuHandler.generateBreadcrumbsModelFromComponents(this.components, this.$scope.component); if (this.$scope.isCreateMode()) { - let createItem = this.getNewComponentBreadcrumbItem(); + const createItem = this.getNewComponentBreadcrumbItem(); if (!breadcrumbsComponentsLvl.menuItems) { breadcrumbsComponentsLvl.menuItems = []; } @@ -905,25 +890,23 @@ export class WorkspaceViewModel { } this.$scope.breadcrumbsModel = [breadcrumbsComponentsLvl, this.$scope.leftBarTabs]; - }; + } private initMenuItems() { - let inCreateMode = this.$scope.isCreateMode(); + const inCreateMode = this.$scope.isCreateMode(); this.$scope.leftBarTabs = new MenuItemGroup(); - //const menuItemsObjects:Array = this.updateMenuItemByRole(this.sdcMenu.component_workspace_menu_option[this.$scope.component.getComponentSubType()], this.role); - let menuItemsObjects:Array = this.updateMenuItemByRole(this.sdcMenu.component_workspace_menu_option[this.$scope.component.getComponentSubType()], this.role); - if(this.$scope.component.getComponentSubType()==="SERVICE") - { - let menuItemsObjectsCategory:Array = this.updateMenuItemByCategory(menuItemsObjects, this.category); - menuItemsObjects = menuItemsObjectsCategory; + let menuItemsObjects: any[] = this.updateMenuItemByRole(this.sdcMenu.component_workspace_menu_option[this.$scope.component.getComponentSubType()], this.role); + if (this.$scope.component.getComponentSubType() === 'SERVICE') { + const menuItemsObjectsCategory: any[] = this.updateMenuItemByCategory(menuItemsObjects, this.category); + menuItemsObjects = menuItemsObjectsCategory; } // Only adding plugins to the workspace if they can be displayed for the current user role _.each(PluginsConfiguration.plugins, (plugin: Plugin) => { if (this.pluginsService.isPluginDisplayedInContext(plugin, this.role, this.$scope.component.getComponentSubType())) { menuItemsObjects.push({ - text: plugin.pluginDisplayOptions["context"].displayName, + text: plugin.pluginDisplayOptions['context'].displayName, action: 'onMenuItemPressed', state: 'workspace.plugins', params: {path: plugin.pluginStateUrl} @@ -931,7 +914,7 @@ export class WorkspaceViewModel { } }); - this.$scope.leftBarTabs.menuItems = menuItemsObjects.map((item:MenuItem) => { + this.$scope.leftBarTabs.menuItems = menuItemsObjects.map((item: MenuItem) => { const menuItem = new MenuItem(item.text, item.callback, item.state, item.action, item.params, item.blockedForTypes, item.disabledCategory); if (menuItem.params) { menuItem.params.state = menuItem.state; @@ -940,7 +923,7 @@ export class WorkspaceViewModel { menuItem.params = {state: menuItem.state}; } menuItem.callback = () => this.$scope[menuItem.action](menuItem.state, menuItem.params); - menuItem.isDisabled = (inCreateMode && States.WORKSPACE_GENERAL != menuItem.state) || + menuItem.isDisabled = (inCreateMode && States.WORKSPACE_GENERAL !== menuItem.state) || (States.WORKSPACE_DEPLOYMENT === menuItem.state && this.$scope.component.modules && this.$scope.component.modules.length === 0 && this.$scope.component.isResource()) || (menuItem.disabledCategory === true); @@ -950,20 +933,54 @@ export class WorkspaceViewModel { if (this.cacheService.get('breadcrumbsComponents')) { this.initBreadcrumbs(); } + else { + this.initBreadcrumbsComponents(); + } } - - private showSuccessNotificationMessage = ():void => { this.Notification.success({ - message: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_FINISHED_DESCRIPTION"), - title: this.$filter('translate')("IMPORT_VF_MESSAGE_CREATE_FINISHED_TITLE") + message: this.$filter('translate')('IMPORT_VF_MESSAGE_CREATE_FINISHED_DESCRIPTION'), + title: this.$filter('translate')('IMPORT_VF_MESSAGE_CREATE_FINISHED_TITLE') }); - }; + } - private setWorkspaceButtonState = (newState:boolean, callback?:Function) => { + private setWorkspaceButtonState = (newState: boolean, callback?: Function) => { this.$scope.unsavedChanges = newState; this.$scope.unsavedChangesCallback = callback; } + private initBreadcrumbsComponents = (): void => { + let breadcrumbsComponentsObservable; + if (this.$stateParams.previousState === 'dashboard') { + breadcrumbsComponentsObservable = this.homeService.getAllComponents(true); + } else if (this.$stateParams.previousState === 'catalog') { + breadcrumbsComponentsObservable = this.catalogService.getCatalog(); + } else { + this.cacheService.remove('breadcrumbsComponentsState'); + this.cacheService.remove('breadcrumbsComponents'); + return; + } + breadcrumbsComponentsObservable.subscribe((components) => { + this.cacheService.set('breadcrumbsComponentsState', this.$stateParams.previousState); + this.cacheService.set('breadcrumbsComponents', components); + this.initBreadcrumbs(); + }); + + } + + private verifyIfDependenciesExist(): void { + let containsDependencies = []; + if (this.$scope.component.componentType && this.$scope.component.uniqueId && + this.$scope.component.lifecycleState === 'CERTIFIED' && (this.$scope.component.isService() || this.$scope.component.getComponentSubType() === 'VF')) { + this.ComponentServiceNg2.getDependencies(this.$scope.component.componentType, this.$scope.component.uniqueId).subscribe((response: IDependenciesServerResponse[]) => { + containsDependencies = response.filter((version) => version.dependencies); + if (containsDependencies.length > 0) { + this.$scope.hasNoDependencies = false; + } else { + this.$scope.hasNoDependencies = true; + } + }); + } + } } diff --git a/catalog-ui/src/app/view-models/workspace/workspace-view.html b/catalog-ui/src/app/view-models/workspace/workspace-view.html index d22262c94a..79dde943dc 100644 --- a/catalog-ui/src/app/view-models/workspace/workspace-view.html +++ b/catalog-ui/src/app/view-models/workspace/workspace-view.html @@ -22,7 +22,8 @@ {{menuComponentTitle}}
    -
    + +
    @@ -53,9 +54,11 @@
    - Switch to the latest version + Switch to the latest version + @@ -104,11 +106,11 @@
    -
    +
    {{getTabTitle()}}
    -
    +
    diff --git a/catalog-ui/src/app/view-models/workspace/workspace.less b/catalog-ui/src/app/view-models/workspace/workspace.less index 518272d45c..5c479c7370 100644 --- a/catalog-ui/src/app/view-models/workspace/workspace.less +++ b/catalog-ui/src/app/view-models/workspace/workspace.less @@ -109,7 +109,7 @@ .general-view-top-progress { width: 30%; margin: 0 auto; - min-width: 150px; + min-width: 140px; } } @@ -189,7 +189,7 @@ display: inline-block; } } - .tab-title{ + .workspace-tab-title { height: 110px; padding-left: 100px; line-height: 110px; @@ -199,6 +199,11 @@ .w-sdc-main-container-body-content { height: 100%; } + + .w-sdc-main-container-body-content-wrapper { + height: 100%; + overflow:hidden; + } } .w-sdc-main-container-body-content { // height:calc(~'100% - @{action_nav_height} - @{tab_title}'); @@ -219,7 +224,7 @@ height: calc(~'100% - @{action_nav_height}'); .w-sdc-main-container-body-content-header { display: flex; - .tab-title { + .workspace-tab-title { flex-grow: 1; } .w-sdc-main-container-body-content-action-buttons { @@ -239,4 +244,58 @@ } } } +// Fix till we remove everything to angular5 and fix all workspace style +.composition{ + .sdc-workspace-container{ + .w-sdc-main-container{ + .w-sdc-main-right-container{ + left:0; + //overflow-y: scroll; + .sdc-workspace-top-bar { + position: absolute; + left: 245px; + right: 0; + z-index: 1; + .not-latest{ + left: 270px; + } + } + .w-sdc-main-container-body-content{ + padding: 0 0 0 0; + } + + > div:first-child{ + padding: 0; + } + } + } + } +} + +.deployment { + + .sdc-workspace-container{ + .w-sdc-main-container{ + .w-sdc-main-right-container{ + left:0; + //overflow-y: scroll; + .sdc-workspace-top-bar { + position: absolute; + left: 245px; + right: 0; + z-index: 1; + .not-latest{ + left: 270px; + } + } + > div:first-child{ + padding: 0; + } + .w-sdc-main-container-body-content-wrapper { + padding: 0px; + } + } + } + } +} -- cgit 1.2.3-korg