From: Arielk Date: Thu, 6 Sep 2018 12:30:15 +0000 (+0300) Subject: Service operation UI merge X-Git-Tag: 1.3.0~118 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=f1e032cf4ae3505eb8acbce56ac978649d6f63d4;p=sdc.git Service operation UI merge Change-Id: I9e8f584b61638696272738220d73086ebd168c96 Issue-ID: SDC-1739 Signed-off-by: Arielk --- diff --git a/catalog-ui/configurations/dev.js b/catalog-ui/configurations/dev.js index 3833e209ed..6ca5445ba4 100644 --- a/catalog-ui/configurations/dev.js +++ b/catalog-ui/configurations/dev.js @@ -84,6 +84,7 @@ const SDC_CONFIG = { "xEcompRequestId": " X-ECOMP-RequestID" }, "imagesPath": "", + "enableWorkflowAssociation": "true", "cpEndPointInstances" : ["cloudep","ossep","personep","premisesep"], "toscaFileExtension":"yaml,yml", "csarFileExtension":"csar", diff --git a/catalog-ui/configurations/menu.js b/catalog-ui/configurations/menu.js index 71eed11448..ad70b03190 100644 --- a/catalog-ui/configurations/menu.js +++ b/catalog-ui/configurations/menu.js @@ -491,6 +491,7 @@ const SDC_MENU_CONFIG = { {"text": "General", "action": "onMenuItemPressed", "state": "workspace.general"}, {"text": "TOSCA Artifacts", "action": "onMenuItemPressed", "state": "workspace.tosca_artifacts"}, {"text": "Composition", "action": "onMenuItemPressed", "state": "workspace.composition.details"}, + {"text": "Operation", "action":"onMenuItemPressed", "state": "workspace.interface_operation"}, {"text": "Activity Log", "action": "onMenuItemPressed", "state": "workspace.activity_log"}, {"text": "Management Workflow", "action": "onMenuItemPressed", "state": "workspace.management_workflow"}, {"text": "Network Call Flow ", "action": "onMenuItemPressed", "state": "workspace.network_call_flow"}, diff --git a/catalog-ui/configurations/prod.js b/catalog-ui/configurations/prod.js index 65b3737e62..08fd20f8e5 100644 --- a/catalog-ui/configurations/prod.js +++ b/catalog-ui/configurations/prod.js @@ -84,6 +84,7 @@ const SDC_CONFIG = { "xEcompRequestId": " X-ECOMP-RequestID" }, "imagesPath": "/sdc1", + "enableWorkflowAssociation": "true", "cpEndPointInstances" : ["cloudep","ossep","personep","premisesep"], "toscaFileExtension":"yaml,yml", "csarFileExtension":"csar", diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.module.ts b/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.module.ts index caf6a3f528..3414769e62 100644 --- a/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.module.ts +++ b/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.module.ts @@ -1,13 +1,15 @@ import {NgModule} from "@angular/core"; import {CommonModule} from "@angular/common"; import {InterfaceOperationComponent} from "./interface-operation.page.component"; +import {UiElementsModule} from "app/ng2/components/ui/ui-elements.module"; @NgModule({ declarations: [ InterfaceOperationComponent ], imports: [ - CommonModule + CommonModule, + UiElementsModule ], exports: [], entryComponents: [ diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.html b/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.html index 25e8672db8..e3bce5ec11 100644 --- a/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.html +++ b/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.html @@ -3,11 +3,13 @@ class="add-btn" [ngClass]="{'disabled': readonly}" data-tests-id="addInterfaceOperation" - (click)="onAddOperation()"> + (click)="onEditOperation()"> Add Operation -
+
+ +
- + ; operationList: Array = []; openOperation: OperationModel; + enableWorkflowAssociation: boolean; + inputs: Array; + isLoading: boolean; @Input() component: IComponent; @Input() readonly: boolean; constructor( - @Inject('$state') private $state:ng.ui.IStateService, + @Inject(SdcConfigToken) sdcConfig: ISdcConfig, private ComponentServiceNg2: ComponentServiceNg2, private WorkflowServiceNg2: WorkflowServiceNg2, private ModalServiceNg2: ModalService, - ) {} + ) { + this.enableWorkflowAssociation = sdcConfig.enableWorkflowAssociation; + } ngOnInit(): void { + this.isLoading = true; this.ComponentServiceNg2.getInterfaceOperations(this.component).subscribe((response: ComponentGenericResponse) => { + if (this.inputs) { + this.isLoading = false; + } let {interfaceOperations} = response; this.component.interfaceOperations = interfaceOperations; - this.operationList = _.toArray(interfaceOperations); + this.operationList = _.toArray(interfaceOperations).sort((a, b) => a.operationType.localeCompare(b.operationType)); + }); + this.ComponentServiceNg2.getComponentInputs(this.component).subscribe((response: ComponentGenericResponse) => { + if (this.component.interfaceOperations) { + this.isLoading = false; + } + this.inputs = response.inputs; }); } @@ -47,13 +64,7 @@ export class InterfaceOperationComponent { return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit(); } - onEditOperation = (operation: OperationModel): void => { - this.ComponentServiceNg2 - .getInterfaceOperation(this.component, operation) - .subscribe(op => this.onAddOperation(op)); - } - - onAddOperation = (operation?: OperationModel): void => { + onEditOperation = (operation?: OperationModel): void => { const modalMap = { create: { modalTitle: 'Create a New Operation', @@ -75,58 +86,60 @@ export class InterfaceOperationComponent { } } - this.ComponentServiceNg2.getComponentInputs(this.component).subscribe((response: ComponentGenericResponse) => { + const cancelButton: ButtonModel = new ButtonModel( + 'Cancel', + 'outline white', + () => { + this.openOperation = null; + this.ModalServiceNg2.closeCurrentModal(); + }, + ); - const cancelButton: ButtonModel = new ButtonModel( - 'Cancel', - 'outline white', - () => { - this.openOperation = null; - this.ModalServiceNg2.closeCurrentModal(); - }, - ); - - const saveButton: ButtonModel = new ButtonModel( - modalData.saveBtnText, - 'blue', - () => { - this.modalInstance.instance.dynamicContent.instance.createInputParamList(); - this.ModalServiceNg2.closeCurrentModal(); - - const {operation, isAssociateWorkflow} = this.modalInstance.instance.dynamicContent.instance; - this.openOperation = {...operation}; - - if (!isAssociateWorkflow) { - operation.workflowId = null; - operation.workflowVersionId = null; - } - - modalData.submitCallback(operation); - }, - this.getDisabled, - ); - - const modalModel: ModalModel = new ModalModel( - 'l', - modalData.modalTitle, - '', - [saveButton, cancelButton], - 'standard', - ); - - this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel); - - this.ModalServiceNg2.addDynamicContentToModal( - this.modalInstance, - OperationCreatorComponent, - { - operation, - inputProperties: response.inputs, - }, - ); - - this.modalInstance.instance.open(); - }); + const saveButton: ButtonModel = new ButtonModel( + modalData.saveBtnText, + 'blue', + () => { + this.modalInstance.instance.dynamicContent.instance.createInputParamList(); + this.ModalServiceNg2.closeCurrentModal(); + + const {operation, isAssociateWorkflow} = this.modalInstance.instance.dynamicContent.instance; + this.openOperation = {...operation}; + + if (!this.enableWorkflowAssociation && !isAssociateWorkflow) { + operation.workflowId = null; + operation.workflowVersionId = null; + } + + modalData.submitCallback(operation); + }, + this.getDisabled, + ); + + const modalModel: ModalModel = new ModalModel( + 'l', + modalData.modalTitle, + '', + [saveButton, cancelButton], + 'standard', + ); + + this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel); + + let input: OperationCreatorInput = { + operation, + inputProperties: this.inputs, + enableWorkflowAssociation: this.enableWorkflowAssociation, + readonly: this.readonly, + isService: this.component.isService() + } + + this.ModalServiceNg2.addDynamicContentToModal( + this.modalInstance, + OperationCreatorComponent, + input, + ); + + this.modalInstance.instance.open(); } onRemoveOperation = (event: Event, operation: OperationModel): void => { @@ -158,6 +171,8 @@ export class InterfaceOperationComponent { this.ComponentServiceNg2.createInterfaceOperation(this.component, operation).subscribe((response: CreateOperationResponse) => { this.openOperation = null; this.operationList.push(new OperationModel(response)); + this.operationList.sort((a, b) => a.operationType.localeCompare(b.operationType)); + if (response.workflowId) { const resourceId = this.component.uuid; const operationId = response.uniqueId; @@ -175,6 +190,15 @@ export class InterfaceOperationComponent { const index = _.findIndex(this.operationList, el => el.uniqueId === operation.uniqueId); this.operationList.splice(index, 1, newOperation); this.component.interfaceOperations = this.operationList; + + if (newOperation.workflowId) { + const resourceId = this.component.uuid; + const operationId = newOperation.uniqueId; + const workflowId = newOperation.workflowId; + const versionId = newOperation.workflowVersionId; + const artifactId = newOperation.artifactUUID; + this.WorkflowServiceNg2.associateWorkflowArtifact(resourceId, operationId, workflowId, versionId, artifactId).subscribe(); + } }); } diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html index c0a6966ceb..84f3910c9b 100644 --- a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html +++ b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html @@ -5,13 +5,14 @@
- - - + +
@@ -20,16 +21,18 @@ type="text" data-tests-id="operationDescription" name="description" + [ngClass]="{'disabled': readonly}" [(ngModel)]="operation.description" [attr.maxLength]="200" />
-
+
@@ -39,6 +42,7 @@ @@ -49,7 +53,7 @@ @@ -61,7 +65,7 @@ Input Parameters Add Input Parameter @@ -70,7 +74,7 @@
Name - Type + Type Property Mandatory - ●●● + ●●●
@@ -98,13 +102,14 @@
+ [onRemoveParam]="onRemoveParam" + [readonly]="readonly">
diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.less b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.less index f962bc2dca..e2b53bee65 100644 --- a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.less +++ b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.less @@ -84,14 +84,8 @@ } /deep/ .cell { - &.field-name { - flex: 2; - } - - - &.field-mandatory { - flex: 0.5; - text-align: center; + &.field-name, &.field-type { + flex: 1; } &.field-property { @@ -100,6 +94,11 @@ } } + &.field-mandatory { + flex: 0.5; + text-align: center; + } + &.remove { min-width: 40px; } diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts index 8d26055feb..d2bad5f02d 100644 --- a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts +++ b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts @@ -5,34 +5,45 @@ import {Subscription} from "rxjs/Subscription"; import {TranslateService} from "app/ng2/shared/translator/translate.service"; import {WorkflowServiceNg2} from 'app/ng2/services/workflow.service'; -import {InputModel, OperationModel, OperationParameter} from 'app/models'; +import {OperationModel, OperationParameter, InputBEModel} from 'app/models'; import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component"; +export interface OperationCreatorInput { + operation: OperationModel, + inputProperties: Array, + enableWorkflowAssociation: boolean, + readonly: boolean, + isService: boolean +} + @Component({ selector: 'operation-creator', templateUrl: './operation-creator.component.html', - styleUrls:['./operation-creator.component.less'], + styleUrls: ['./operation-creator.component.less'], providers: [TranslateService] }) export class OperationCreatorComponent { - input: any; + input: OperationCreatorInput; operation: OperationModel; workflows: Array = []; workflowVersions: Array = []; inputProperties: Array = []; - inputPropertyTypes: {}; + inputPropertyTypes: { [key: string]: string }; inputParameters: Array = []; noAssignInputParameters: Array = []; assignInputParameters: { [key: string]: { [key: string]: Array; }; } = {}; - isAssociateWorkflow: boolean = false; + enableWorkflowAssociation: boolean; + isAssociateWorkflow: boolean; isEditMode: boolean = false; isLoading: boolean = false; + readonly: boolean; + isService: boolean; propertyTooltipText: String; @@ -44,52 +55,64 @@ export class OperationCreatorComponent { ngOnInit() { + this.readonly = this.input.readonly; + this.isService = this.input.isService; + this.enableWorkflowAssociation = this.input.enableWorkflowAssociation && !this.isService; + this.inputProperties = _.map(this.input.inputProperties, - (input: InputModel) => new DropdownValue(input.uniqueId, input.name) + (input: InputBEModel) => new DropdownValue(input.uniqueId, input.name) ); this.inputPropertyTypes = {}; - _.forEach(this.input.inputProperties, (input: InputModel) => { + _.forEach(this.input.inputProperties, (input: InputBEModel) => { this.inputPropertyTypes[input.uniqueId] = input.type; }); - const inputOperation = this.input.operation; + const inputOperation = this.input.operation; this.operation = new OperationModel(inputOperation || {}); - const buildInputParams = () => { - if (inputOperation.inputParams) { - this.inputParameters = []; - _.forEach(inputOperation.inputParams.listToscaDataDefinition, (input: OperationParameter) => { - this.addParam(input); + if (this.enableWorkflowAssociation) { + this.isLoading = true; + this.workflowServiceNg2.getWorkflows().subscribe(workflows => { + this.isLoading = false; + this.workflows = _.map(workflows, (workflow: any) => { + return new DropdownValue(workflow.id, workflow.name); }); - } - } - - this.isLoading = true; - this.workflowServiceNg2.getWorkflows().subscribe(workflows => { - this.isLoading = false; - - this.workflows = _.map(workflows, (workflow: any) => { - return new DropdownValue(workflow.id, workflow.name); + this.reconstructOperation(); }); + } else { + this.reconstructOperation(); + } - if (inputOperation) { - if (inputOperation.workflowVersionId) { - this.isAssociateWorkflow = true; - this.onSelectWorkflow(inputOperation.workflowVersionId).add(buildInputParams); - } else { - this.inputParameters = this.noAssignInputParameters; - this.isAssociateWorkflow = false; - buildInputParams(); - } + } - if (inputOperation.uniqueId) { - this.isEditMode = true; - } + reconstructOperation = () => { + const inputOperation = this.input.operation; + if (inputOperation) { + if (!this.enableWorkflowAssociation || !inputOperation.workflowVersionId || this.isService) { + this.inputParameters = this.noAssignInputParameters; + this.isAssociateWorkflow = false; + this.buildInputParams(); + } else { + this.isAssociateWorkflow = true; + this.onSelectWorkflow(inputOperation.workflowVersionId).add(this.buildInputParams); } - }); + if (inputOperation.uniqueId) { + this.isEditMode = true; + } + } + } + buildInputParams = () => { + if (this.input.operation.inputParams) { + _.forEach( + [...this.input.operation.inputParams.listToscaDataDefinition].sort((a, b) => a.name.localeCompare(b.name)), + (input: OperationParameter) => { + this.addParam(input); + } + ); + } } onSelectWorkflow(selectedVersionId?: string): Subscription { @@ -104,7 +127,9 @@ export class OperationCreatorComponent { this.isLoading = false; this.workflowVersions = _.map( - _.filter(versions, version => version.state === this.workflowServiceNg2.VERSION_STATE_CERTIFIED), + _.filter( + versions, version => version.state === this.workflowServiceNg2.VERSION_STATE_CERTIFIED + ).sort((a, b) => a.name.localeCompare(b.name)), (version: any) => { if (!this.assignInputParameters[this.operation.workflowId][version.id]) { this.assignInputParameters[this.operation.workflowId][version.id] = _.map(version.inputs, (input: any) => { @@ -114,14 +139,15 @@ export class OperationCreatorComponent { property: null, mandatory: input.mandatory, }); - }); + }) + .sort((a, b) => a.name.localeCompare(b.name)); } - return new DropdownValue(version.id, `v. ${version.name}`); + return new DropdownValue(version.id, `V ${version.name}`); } ); - if (!selectedVersionId && versions.length) { - this.operation.workflowVersionId = _.last(versions.sort()).id; + if (!selectedVersionId && this.workflowVersions.length) { + this.operation.workflowVersionId = _.last(this.workflowVersions).value; } this.changeWorkflowVersion(); }); diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.html b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.html index 2a72177621..25ecd2932e 100644 --- a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.html +++ b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.html @@ -1,9 +1,10 @@
- + [(value)]="param.name" + [readonly]="readonly"> + {{param.name}}
@@ -13,7 +14,8 @@ data-tests-id="paramType" [values]="propTypeEnum" [(value)]="param.type" - (valueChange)="onChangeType()"> + (valueChange)="onChangeType()" + [readonly]="readonly">
{{param.type}}
@@ -22,7 +24,8 @@ + [(value)]="param.property" + [readonly]="readonly">
@@ -30,11 +33,12 @@ + [(checked)]="param.mandatory" + [ngClass]="{'disabled':readonly}">
-
+
; - @Input() propTypes: {}; + @Input() propTypes: { [key: string]: string }; @Input() onRemoveParam: Function; @Input() isAssociateWorkflow: boolean; + @Input() readonly: boolean; - propTypeEnum: Array = ['boolean', 'float', 'integer', 'string']; + propTypeEnum: Array = []; filteredInputProps: Array = []; + constructor(private dataTypeService:DataTypeService) {} + ngOnInit() { + const types = PROPERTY_DATA.TYPES.concat( + _.filter( + Object.keys(this.dataTypeService.getAllDataTypes()), + type => PROPERTY_DATA.TYPES.indexOf(type) === -1 + ) + ); + this.propTypeEnum = _.filter( + types, + type => _.toArray(this.propTypes).indexOf(type) > -1 + ); this.onChangeType(); } 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 d79cfc621f..cabaccd1d5 100644 --- a/catalog-ui/src/app/ng2/services/data-type.service.ts +++ b/catalog-ui/src/app/ng2/services/data-type.service.ts @@ -43,6 +43,10 @@ export class DataTypeService { return this.dataTypes[typeName]; } + public getAllDataTypes(): DataTypesMap { + return this.dataTypes; + } + public getDerivedDataTypeProperties(dataTypeObj: DataTypeModel, propertiesArray: Array, parentName: string) { //push all child properties to array diff --git a/catalog-ui/src/assets/languages/en_US.json b/catalog-ui/src/assets/languages/en_US.json index 64be28506b..48751c9f73 100644 --- a/catalog-ui/src/assets/languages/en_US.json +++ b/catalog-ui/src/assets/languages/en_US.json @@ -453,6 +453,7 @@ "=========== OPERATION CREATOR ============": "", "OPERATION_PROPERTY_TOOLTIP_TEXT": "VNF properties are defined by the input parameter type. In case you can't find a certain parameter, it might be due to a wrong type selection.", + "SERVICE_OPERATION_PROPERTY_TOOLTIP_TEXT": "Service properties are defined by the input parameter type. In case you can't find a certain parameter, it might be due to a wrong type selection.", "=========== PLUGIN NOT CONNECTED ===========": "", "PLUGIN_NOT_CONNECTED_ERROR_MAIN": "The \"{{pluginName}}\" plugin is currently unavailable.",