Enhance operations to associate workflows 37/58237/4
authorArielk <Ariel.Kenan@amdocs.com>
Tue, 31 Jul 2018 09:59:36 +0000 (12:59 +0300)
committerAvi Gaffa <avi.gaffa@amdocs.com>
Thu, 2 Aug 2018 08:56:34 +0000 (08:56 +0000)
Change-Id: Iacf74ee333a3bc2e76e764c28ae660322bc9e6e4
Issue-ID: SDC-1535
Signed-off-by: Arielk <Ariel.Kenan@amdocs.com>
15 files changed:
catalog-ui/configurations/dev.js
catalog-ui/configurations/prod.js
catalog-ui/src/app/models/operation.ts
catalog-ui/src/app/ng2/app.module.ts
catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.less
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.html
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.less
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.ts
catalog-ui/src/app/ng2/services/workflow.service.ts [new file with mode: 0644]
catalog-ui/src/app/utils/common-utils.ts
catalog-ui/src/assets/languages/en_US.json
catalog-ui/webpack.server.js

index 7e67dbb..1dc8c81 100644 (file)
@@ -48,6 +48,8 @@ const SDC_CONFIG = {
                "GET_lifecycle_state_UNDOCHECKOUT":"lifecycleState/UNDOCHECKOUT",
                "root": "/sdc1/feProxy/rest",
         "no_proxy_root": "/sdc1/rest",
+               "workflow_root": "/sdc1/feProxy/wf",
+               "POST_workflow_artifact": "/v1/catalog",
                "PUT_service": "/v1/catalog/services/:id/metadata",
                "GET_download_artifact": "/v1/catalog/",
         "GET_SDC_Version": "/version",
index adbd650..cd94f53 100644 (file)
@@ -48,6 +48,8 @@ const SDC_CONFIG = {
                "GET_lifecycle_state_UNDOCHECKOUT":"lifecycleState/UNDOCHECKOUT",
                "root": "/sdc1/feProxy/rest",
         "no_proxy_root": "/sdc1/rest",
+               "workflow_root": "/sdc1/feProxy/wf",
+               "POST_workflow_artifact": "/v1/catalog",
                "PUT_service": "/v1/catalog/services/:id/metadata",
                "GET_download_artifact": "/v1/catalog/",
         "GET_SDC_Version": "/version",
index 55fcd82..2a5298c 100644 (file)
@@ -1,27 +1,43 @@
 'use strict';
 
-export class OperationParam {
-    paramName: string = '';
-    paramId: string = '';
+export class OperationParameter {
+    name: string;
+    type: string;
+    property: string;
+    mandatory: boolean;
 
-    constructor(param?: OperationParam) {
+    constructor(param?: OperationParameter) {
         if (param) {
-            this.paramId = param.paramId;
-            this.paramName = param.paramName;
+            this.name = param.name;
+            this.type = param.type;
+            this.property = param.property;
+            this.mandatory = param.mandatory;
         }
     }
 }
 
 export interface IOperationParamsList {
-    listToscaDataDefinition: Array<OperationParam>;
+    listToscaDataDefinition: Array<OperationParameter>;
 }
 
 export class OperationModel {
+    operationType: string;
     description: string;
+    uniqueId: string;
+
     inputParams: IOperationParamsList;
-    operationType: string;
     outputParams: IOperationParamsList;
-    uniqueId: string;
+
+    workflowId: string;
+    workflowVersionId: string;
+
+    protected OperationTypeEnum: Array<String> = [
+        'Create',
+        'Delete',
+        'Instantiate',
+        'Start',
+        'Stop'
+    ];
 
     constructor(operation?: any) {
         if (operation) {
@@ -30,16 +46,18 @@ export class OperationModel {
             this.operationType = operation.operationType;
             this.outputParams = operation.outputParams;
             this.uniqueId = operation.uniqueId;
+            this.workflowId = operation.workflowId;
+            this.workflowVersionId = operation.workflowVersionId;
         }
     }
 
-    public createInputParamsList(inputParams: Array<OperationParam>): void {
+    public createInputParamsList(inputParams: Array<OperationParameter>): void {
         this.inputParams = {
             listToscaDataDefinition: inputParams
         };
     }
 
-    public createOutputParamsList(outputParams: Array<OperationParam>): void {
+    public createOutputParamsList(outputParams: Array<OperationParameter>): void {
         this.outputParams = {
             listToscaDataDefinition: outputParams
         };
index c949a73..7a845ef 100644 (file)
@@ -41,11 +41,12 @@ import { ComponentServiceNg2 } from "./services/component-services/component.ser
 import { ComponentServiceFactoryNg2 } from "./services/component-services/component.service.factory";
 import { ServiceServiceNg2 } from "./services/component-services/service.service";
 import { ComponentInstanceServiceNg2 } from "./services/component-instance-services/component-instance.service";
+import { WorkflowServiceNg2 } from './services/workflow.service';
 import { ModalService } from "./services/modal.service";
 import { UiElementsModule } from "./components/ui/ui-elements.module";
 import { ConnectionWizardModule } from "./pages/connection-wizard/connection-wizard.module";
-import {InterfaceOperationModule} from "./pages/interface-operation/interface-operation.module";
-import {OperationCreatorModule} from "./pages/interface-operation/operation-creator/operation-creator.module";
+import { InterfaceOperationModule } from "./pages/interface-operation/interface-operation.module";
+import { OperationCreatorModule } from "./pages/interface-operation/operation-creator/operation-creator.module";
 import { LayoutModule } from "./components/layout/layout.module";
 import { UserService } from "./services/user.service";
 import { DynamicComponentService } from "./services/dynamic-component.service";
@@ -135,6 +136,7 @@ export function configServiceFactory(config: ConfigService) {
         ModalService,
         ServiceServiceNg2,
         AutomatedUpgradeService,
+        WorkflowServiceNg2,
         HttpService,
         UserService,
         PoliciesService,
index c58e1de..010a1f9 100644 (file)
@@ -1,11 +1,15 @@
 import * as _ from "lodash";
 import {Component, Input, ComponentRef, Inject} from '@angular/core';
 import {Component as IComponent} from 'app/models/components/component';
+
+import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component';
 import {ModalService} from 'app/ng2/services/modal.service';
 import {ModalModel, ButtonModel, InputModel, OperationModel, CreateOperationResponse} from 'app/models';
-import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component';
+
 import {ComponentServiceNg2} from 'app/ng2/services/component-services/component.service';
 import {ComponentGenericResponse} from 'app/ng2/services/responses/component-generic-response';
+import {WorkflowServiceNg2} from 'app/ng2/services/workflow.service';
+
 import {OperationCreatorComponent} from './operation-creator/operation-creator.component';
 
 @Component({
@@ -27,6 +31,7 @@ export class InterfaceOperationComponent {
     constructor(
         @Inject('$state') private $state:ng.ui.IStateService,
         private ComponentServiceNg2: ComponentServiceNg2,
+        private WorkflowServiceNg2: WorkflowServiceNg2,
         private ModalServiceNg2: ModalService,
     ) {}
 
@@ -87,8 +92,15 @@ export class InterfaceOperationComponent {
                 () => {
                     this.modalInstance.instance.dynamicContent.instance.createInputParamList();
                     this.ModalServiceNg2.closeCurrentModal();
-                    const {operation} = this.modalInstance.instance.dynamicContent.instance;
-                    this.openOperation = operation;
+
+                    const {operation, isAssociateWorkflow} = this.modalInstance.instance.dynamicContent.instance;
+                    this.openOperation = {...operation};
+
+                    if (!isAssociateWorkflow) {
+                        operation.workflowId = null;
+                        operation.workflowVersionId = null;
+                    }
+
                     modalData.submitCallback(operation);
                 },
                 this.getDisabled,
@@ -103,6 +115,7 @@ export class InterfaceOperationComponent {
             );
 
             this.modalInstance = this.ModalServiceNg2.createCustomModal(modalModel);
+
             this.ModalServiceNg2.addDynamicContentToModal(
                 this.modalInstance,
                 OperationCreatorComponent,
@@ -145,22 +158,15 @@ export class InterfaceOperationComponent {
         this.ComponentServiceNg2.createInterfaceOperation(this.component, operation).subscribe((response: CreateOperationResponse) => {
             this.openOperation = null;
 
-            const workflowId = response.artifactUUID;
-            const operationId = response.uniqueId;
-            const resourceId = this.component.uuid;
-
-            const queryParams = {
-                id: workflowId,
-                operationID: operationId,
-                uuid: resourceId,
-                displayMode: 'create',
-            };
-
-            this.$state.go('workspace.plugins', {
-                path: 'workflowDesigner',
-                queryParams
-            });
+            if (response.workflowId) {
+                const resourceId = this.component.uuid;
+                const operationId = response.uniqueId;
+                const workflowId = response.workflowId;
+                const versionId = response.workflowVersionId;
+                const artifactId = response.artifactUUID;
 
+                this.WorkflowServiceNg2.associateWorkflowArtifact(resourceId, operationId, workflowId, versionId, artifactId);
+            }
         });
     }
 
index 9e47cd5..c0a6966 100644 (file)
@@ -1,16 +1,17 @@
 <div class="operation-creator">
+    <loader [display]="isLoading" [size]="'large'" [relative]="true"></loader>
+
     <form class="w-sdc-form">
 
         <div class="side-by-side">
             <div class="i-sdc-form-item">
-                <label class="i-sdc-form-label">Operation Type</label>
-                <input
-                    type="text"
-                    data-tests-id="operationType"
-                    name="operationType"
-                    [(ngModel)]="operation.operationType"
-                    [attr.maxLength]="200"
-                    [disabled]="isEditMode" />
+                <label class="i-sdc-form-label" [ngClass]="{'required': !isEditMode}">Operation Type</label>
+                <ui-element-dropdown
+                    data-tests-id="operationTypeDropdown"
+                    [values]="operation.OperationTypeEnum"
+                    [(value)]="operation.operationType"
+                    [readonly]="isEditMode">
+                </ui-element-dropdown>
             </div>
 
             <div class="i-sdc-form-item" >
             </div>
         </div>
 
+        <div class="i-sdc-form-item">
+            <checkbox
+                [label]="'Assign Workflow'"
+                [(checked)]="isAssociateWorkflow"
+                (checkedChange)="toggleAssociateWorkflow()"
+                data-tests-id="checkbox-assign-workflow">
+            </checkbox>
+        </div>
+
+        <div class="side-by-side" *ngIf="isAssociateWorkflow">
+            <div class="i-sdc-form-item">
+                <label class="i-sdc-form-label required">Workflow</label>
+                <ui-element-dropdown
+                    data-tests-id="associated-workflow"
+                    [values]="workflows"
+                    [(value)]="operation.workflowId"
+                    (valueChange)="onSelectWorkflow()">
+                </ui-element-dropdown>
+            </div>
+
+            <div class="i-sdc-form-item">
+                <label class="i-sdc-form-label required">Workflow Version</label>
+                <ui-element-dropdown
+                    data-tests-id="associated-workflow-version"
+                    [ngClass]="{'disabled': !operation.workflowId}"
+                    [values]="workflowVersions"
+                    [(value)]="operation.workflowVersionId"
+                    (valueChange)="changeWorkflowVersion()">
+                </ui-element-dropdown>
+            </div>
+        </div>
+
         <div class="separator-buttons">
             <span class="input-param-title">Input Parameters</span>
             <a
-                class="add-param-link"
+                class="add-param-link add-btn"
+                *ngIf="!isAssociateWorkflow"
                 data-tests-id="addInputParameter"
-                [ngClass]="{'disabled':!isAddAllowed()}"
-                (click)="addParam()">
-                Add Input Parameter
-            </a>
+                [ngClass]="{'disabled':!isParamsValid()}"
+                (click)="addParam()">Add Input Parameter</a>
         </div>
 
         <div class="generic-table">
             <div class="header-row table-row">
-                <span class="cell header-cell">Name</span>
-                <span class="cell header-cell">Property Name</span>
-                <span class="cell header-cell"></span>
+                <span class="cell header-cell field-name">Name</span>
+                <span class="cell header-cell">Type</span>
+                <span class="cell header-cell field-property">
+                    Property
+                    <span
+                        *ngIf="!isAssociateWorkflow"
+                        class="sprite-new info-icon"
+                        tooltip="{{propertyTooltipText}}"
+                        tooltipDelay="0">
+                    </span>
+                </span>
+                <span class="cell header-cell field-mandatory" *ngIf="!isAssociateWorkflow">Mandatory</span>
+                <span class="cell header-cell remove" *ngIf="!isAssociateWorkflow">●●●</span>
             </div>
 
-            <div class="empty-msg data-row" *ngIf="inputParams.length === 0">
-                No data to display.
+            <div class="empty-msg data-row" *ngIf="inputParameters.length === 0">
+                <div>NO PARAMETERS TO SHOW</div>
+                <div *ngIf="isAssociateWorkflow && !operation.workflowVersionId">
+                    <div *ngIf="workflows.length">
+                        <span class="bold-message">Select Workflow and Workflow Version above</span>
+                        <span>in order to see the parameters</span>
+                    </div>
+                    <div *ngIf="!workflows.length">
+                        Only <span class="bold-message">certified</span> workflow versions can be assigned to an operation
+                    </div>
+                </div>
             </div>
 
             <param-row
-                *ngFor="let param of inputParams; let idx=index"
+                *ngFor="let param of inputParameters; let idx=index"
                 class="data-row"
+                [isAssociateWorkflow]="isAssociateWorkflow"
                 [param]="param"
                 [inputProps]="inputProperties"
+                [propTypes]="inputPropertyTypes"
                 [onRemoveParam]="onRemoveParam">
             </param-row>
         </div>
index 289dd5b..f962bc2 100644 (file)
         max-height: 233px;
 
         .header-row .header-cell {
-            &:last-child {
-                padding: 0;
+            &.remove {
+                padding: 8px;
+            }
+            .info-icon {
+                float: right;
+            }
+            .tooltip-inner {
+                &.tooltip-inner {
+                    &.tooltip-inner {
+                        max-width: 230px;
+                    }
+                }
             }
         }
 
         .data-row {
             &.empty-msg {
-                padding: 6px 14px;
+                .bold-message {
+                    font-weight: 600;
+                }
+
+                :first-child {
+                    &:not(:only-child) {
+                        margin: 6px 0;
+                    }
+                }
+
+                display: flex;
+                flex-direction: column;
+                justify-content: center;
+                align-items: center;
+                padding: 11px 0;
             }
         }
 
         /deep/ .cell {
-            &:last-child {
+            &.field-name {
+                flex: 2;
+            }
+
+
+            &.field-mandatory {
+                flex: 0.5;
+                text-align: center;
+            }
+
+            &.field-property {
+                &, &:last-child {
+                    flex: 1;
+                }
+            }
+
+            &.remove {
                 min-width: 40px;
             }
         }
index cc7b5fe..8d26055 100644 (file)
 import * as _ from "lodash";
 import {Component} from '@angular/core';
+
+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 {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component";
-import {InputModel, OperationModel, OperationParam} from 'app/models';
 
 @Component({
     selector: 'operation-creator',
     templateUrl: './operation-creator.component.html',
     styleUrls:['./operation-creator.component.less'],
+    providers: [TranslateService]
 })
 
 export class OperationCreatorComponent {
 
-    inputProperties: Array<DropdownValue>;
     input: any;
-    inputParams: Array<OperationParam> = [];
     operation: OperationModel;
+
+    workflows: Array<DropdownValue> = [];
+    workflowVersions: Array<DropdownValue> = [];
+    inputProperties: Array<DropdownValue> = [];
+    inputPropertyTypes: {};
+
+    inputParameters: Array<OperationParameter> = [];
+    noAssignInputParameters: Array<OperationParameter> = [];
+    assignInputParameters: { [key: string]: { [key: string]: Array<OperationParameter>; }; } = {};
+
+    isAssociateWorkflow: boolean = false;
     isEditMode: boolean = false;
+    isLoading: boolean = false;
+
+    propertyTooltipText: String;
+
+    constructor(private workflowServiceNg2: WorkflowServiceNg2, private translateService: TranslateService) {
+        this.translateService.languageChangedObservable.subscribe(lang => {
+            this.propertyTooltipText = this.translateService.translate("OPERATION_PROPERTY_TOOLTIP_TEXT");
+        });
+    }
 
     ngOnInit() {
-        this.operation = new OperationModel(this.input.operation || {});
 
-        if (this.input.operation) {
-            let {inputParams} = this.input.operation;
+        this.inputProperties = _.map(this.input.inputProperties,
+            (input: InputModel) => new DropdownValue(input.uniqueId, input.name)
+        );
+
+        this.inputPropertyTypes = {};
+        _.forEach(this.input.inputProperties, (input: InputModel) => {
+            this.inputPropertyTypes[input.uniqueId] = input.type;
+        });
 
-            if (inputParams) {
-                _.forEach(inputParams.listToscaDataDefinition, (input: OperationParam) => {
+        const inputOperation = <OperationModel>this.input.operation;
+        this.operation = new OperationModel(inputOperation || {});
+
+        const buildInputParams = () => {
+            if (inputOperation.inputParams) {
+                this.inputParameters = [];
+                _.forEach(inputOperation.inputParams.listToscaDataDefinition, (input: OperationParameter) => {
                     this.addParam(input);
                 });
             }
+        }
+
+        this.isLoading = true;
+        this.workflowServiceNg2.getWorkflows().subscribe(workflows => {
+            this.isLoading = false;
+
+            this.workflows = _.map(workflows, (workflow: any) => {
+                return new DropdownValue(workflow.id, workflow.name);
+            });
+
+            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;
+                }
+            }
+        });
 
-            if (this.input.operation.uniqueId) {
-                this.isEditMode = true;
+
+    }
+
+    onSelectWorkflow(selectedVersionId?: string): Subscription {
+
+        this.operation.workflowVersionId = selectedVersionId || null;
+        if (!this.assignInputParameters[this.operation.workflowId]) {
+            this.assignInputParameters[this.operation.workflowId] = {};
+        }
+
+        this.isLoading = true;
+        return this.workflowServiceNg2.getWorkflowVersions(this.operation.workflowId).subscribe((versions: Array<any>) => {
+            this.isLoading = false;
+
+            this.workflowVersions = _.map(
+                _.filter(versions, version => version.state === this.workflowServiceNg2.VERSION_STATE_CERTIFIED),
+                (version: any) => {
+                    if (!this.assignInputParameters[this.operation.workflowId][version.id]) {
+                        this.assignInputParameters[this.operation.workflowId][version.id] = _.map(version.inputs, (input: any) => {
+                            return new OperationParameter({
+                                name: input.name,
+                                type: input.type && input.type.toLowerCase(),
+                                property: null,
+                                mandatory: input.mandatory,
+                            });
+                        });
+                    }
+                    return new DropdownValue(version.id, `v. ${version.name}`);
+                }
+            );
+
+            if (!selectedVersionId && versions.length) {
+                this.operation.workflowVersionId = _.last(versions.sort()).id;
+            }
+            this.changeWorkflowVersion();
+        });
+
+    }
+
+    changeWorkflowVersion() {
+        this.inputParameters = this.assignInputParameters[this.operation.workflowId][this.operation.workflowVersionId];
+    }
+
+    toggleAssociateWorkflow() {
+
+        if (!this.isAssociateWorkflow) {
+            this.inputParameters = this.noAssignInputParameters;
+        } else {
+            if (!this.operation.workflowId || !this.operation.workflowVersionId) {
+                this.inputParameters = [];
+            } else {
+                this.inputParameters = this.assignInputParameters[this.operation.workflowId][this.operation.workflowVersionId];
             }
         }
 
-        this.inputProperties = _.map(this.input.inputProperties,
-            (input: InputModel) => new DropdownValue(input.uniqueId, input.name)
-        );
     }
 
-    addParam(param?: OperationParam): void {
-        this.inputParams.push(new OperationParam(param));
+    addParam(param?: OperationParameter): void {
+        this.inputParameters.push(new OperationParameter(param));
     }
 
-    isAddAllowed(): boolean {
-        if (this.inputParams.length === 0) {
-            return true;
+    isParamsValid(): boolean {
+
+        for (let ctr=0; ctr<this.inputParameters.length; ctr++) {
+            if (!this.inputParameters[ctr].name || !this.inputParameters[ctr].property) {
+                return false;
+            }
         }
+        return true;
 
-        const {paramId, paramName} = _.last(this.inputParams);
-        return paramId && paramName.length > 0;
     }
 
-    onRemoveParam = (param: OperationParam): void  => {
-        let index = _.indexOf(this.inputParams, param);
-        this.inputParams.splice(index, 1);
+    onRemoveParam = (param: OperationParameter): void => {
+        let index = _.indexOf(this.inputParameters, param);
+        this.inputParameters.splice(index, 1);
     }
 
     createInputParamList(): void {
-        this.operation.createInputParamsList(this.inputParams);
+        this.operation.createInputParamsList(this.inputParameters);
     }
 
     checkFormValidForSubmit(): boolean {
-        return this.operation.operationType && this.operation.operationType.length > 0 && this.isAddAllowed();
+        return this.operation.operationType &&
+            (!this.isAssociateWorkflow || this.operation.workflowVersionId) &&
+            this.isParamsValid();
     }
 
 }
index 86d7628..2a72177 100644 (file)
@@ -1,18 +1,40 @@
-<div class="cell">
+<div class="cell field-name">
     <input
+        *ngIf="!isAssociateWorkflow"
         type="text"
-        data-tests-id="inputParamName"
-        [(ngModel)]="param.paramName" />
+        data-tests-id="paramName"
+        [(ngModel)]="param.name" />
+    <span *ngIf="isAssociateWorkflow">{{param.name}}</span>
 </div>
 
-<ui-element-dropdown
-    class="cell"
-    data-tests-id="inputParamProperty"
-    [values]="inputProps"
-    [(value)]="param.paramId">
-</ui-element-dropdown>
+<div class="cell field-type">
+    <ui-element-dropdown
+        *ngIf="!isAssociateWorkflow"
+        data-tests-id="paramType"
+        [values]="propTypeEnum"
+        [(value)]="param.type"
+        (valueChange)="onChangeType()">
+    </ui-element-dropdown>
+    <span *ngIf="isAssociateWorkflow">{{param.type}}</span>
+</div>
+
+<div class="cell field-property">
+    <ui-element-dropdown
+        data-tests-id="paramProperty"
+        [values]="filteredInputProps"
+        [(value)]="param.property">
+    </ui-element-dropdown>
+</div>
+
+<div class="cell field-mandatory" *ngIf="!isAssociateWorkflow">
+    <checkbox
+        *ngIf="!isAssociateWorkflow"
+        data-tests-id="paramMandatory"
+        [(checked)]="param.mandatory">
+    </checkbox>
+</div>
 
-<div class="cell remove">
+<div class="cell remove" *ngIf="!isAssociateWorkflow">
     <span
         class="sprite-new delete-item-icon"
         data-tests-id="removeInputParam"
index 9abd7c7..8795d22 100644 (file)
@@ -5,7 +5,7 @@
     align-items: center;
     justify-content: center;
 
-    .delete-item-icon {
+    .delete-btn {
         &:hover {
             cursor: pointer;
         }
 
 
 .cell {
-    padding: 0;
+    padding: 10px;
+    display: flex;
+    align-items: center;
+
+    > * {
+        flex-basis: 100%;
+    }
 
     /deep/ select {
         height: 30px;
-        border: none;
     }
 
     input {
         height: 30px;
-        border: none;
         padding-left: 10px;
     }
+
+    &.field-property {
+        &:last-child {
+            flex: 1;
+        }
+    }
 }
index 01e0629..75d4fcf 100644 (file)
@@ -1,6 +1,6 @@
 import {Component, Input} from '@angular/core';
 import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component";
-import {OperationParam} from 'app/models';
+import {OperationParameter} from 'app/models';
 
 @Component({
     selector: 'param-row',
@@ -9,7 +9,22 @@ import {OperationParam} from 'app/models';
 })
 
 export class ParamRowComponent {
-    @Input() param: OperationParam;
+    @Input() param: OperationParameter;
     @Input() inputProps: Array<DropdownValue>;
+    @Input() propTypes: {};
     @Input() onRemoveParam: Function;
+    @Input() isAssociateWorkflow: boolean;
+
+    propTypeEnum: Array<string> = ['boolean', 'float', 'integer', 'string'];
+    filteredInputProps: Array<DropdownValue> = [];
+
+    ngOnInit() {
+        this.onChangeType();
+    }
+
+    onChangeType() {
+        this.filteredInputProps = _.filter(this.inputProps, prop => {
+            return this.propTypes[prop.value] === this.param.type;
+        });
+    }
 }
diff --git a/catalog-ui/src/app/ng2/services/workflow.service.ts b/catalog-ui/src/app/ng2/services/workflow.service.ts
new file mode 100644 (file)
index 0000000..7e596e1
--- /dev/null
@@ -0,0 +1,52 @@
+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";
+
+@Injectable()
+export class WorkflowServiceNg2 {
+
+    protected baseUrl;
+    protected catalogBaseUrl;
+
+    VERSION_STATE_CERTIFIED = 'CERTIFIED';
+
+    constructor(private http: HttpService, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) {
+        this.baseUrl = sdcConfig.api.workflow_root;
+        this.catalogBaseUrl = sdcConfig.api.POST_workflow_artifact;
+    }
+
+    public getWorkflows(filterCertified: boolean = true): Observable<any> {
+        return this.http.get(this.baseUrl + '/workflows' + (filterCertified ? '?versionState=' + this.VERSION_STATE_CERTIFIED : ''))
+            .map((res:Response) => {
+                return res.json().results;
+            });
+    }
+
+    public getWorkflowVersions(workflowId: string, filterCertified: boolean = true): Observable<any> {
+        return this.http.get(this.baseUrl + '/workflows/' + workflowId + '/versions' + (filterCertified ? '?state=' + this.VERSION_STATE_CERTIFIED : ''))
+            .map((res:Response) => {
+                return res.json().results;
+            });
+    }
+
+    public updateWorkflowVersion(workflowId: string, versionId: string, payload: any): Observable<any> {
+        return this.http.put(this.baseUrl + '/workflows/' + workflowId + '/versions/' + versionId, payload)
+            .map((res:Response) => {
+                return res;
+            });
+    }
+
+    public associateWorkflowArtifact(resourceUuid, operationId, workflowId, workflowVersionId, artifactUuid): Observable<any> {
+        return this.http.post(this.baseUrl + '/workflows/' + workflowId + '/versions/' + workflowVersionId + '/artifact-deliveries',
+            {
+                endpoint: this.catalogBaseUrl + '/resources/' + resourceUuid + '/interfaces/' + operationId + '/artifacts/' + artifactUuid,
+                method: 'POST'
+            })
+            .map((res:Response) => {
+                return res.json();
+            });
+    }
+
+}
index d215183..0c6a8b6 100644 (file)
@@ -153,13 +153,23 @@ export class CommonUtils {
                         });
                         if (inputs) {
                             const inputParams = _.map(inputs.listToscaDataDefinition, (input:any) => {
-                                return {paramName: input.name, paramId: input.inputId};
+                                return {
+                                    name: input.name,
+                                    property: input.inputId,
+                                    type: input.type,
+                                    mandatory: input.mandatory
+                                };
                             });
                             operation.createInputParamsList(inputParams);
                         }
                         if (outputs) {
                             const outputParams = _.map(outputs.listToscaDataDefinition, (output:any) => {
-                                return {paramName: output.name, paramId: output.outputId};
+                                return {
+                                    name: output.name,
+                                    property: output.inputId,
+                                    type: output.type,
+                                    mandatory: output.mandatory
+                                };
                             });
                             operation.createOutputParamsList(outputParams);
                         }
index 612d14e..64be285 100644 (file)
     "SERVICE_PATH_SELECTOR_HIDE_ALL_VALUE" : "⚊ Hide all ⚊",
     "SERVICE_PATH_SELECTOR_SHOW_ALL_VALUE" : "⚊ Show all ⚊",
 
+    "=========== 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.",
+
     "=========== PLUGIN NOT CONNECTED ===========": "",
     "PLUGIN_NOT_CONNECTED_ERROR_MAIN": "The \"{{pluginName}}\" plugin is currently unavailable.",
     "PLUGIN_NOT_CONNECTED_ERROR_SUB": "Please try again later.",
index a0f6fb1..b8821cd 100644 (file)
@@ -4,7 +4,7 @@ const mockApis = require('./configurations/mock.json').sdcConfig;
 const proxy = require('http-proxy-middleware');
 const devPort = 9000;
 const fePort = 8181;
-const loclahost = "192.168.33.10"; // "localhost"
+const localhost = "localhost";
 
 module.exports = function(env) {
 
@@ -25,65 +25,79 @@ module.exports = function(env) {
                        exclude: ['node_modules']
                },
                setup: server => {
-               let userType = mockApis.userTypes[env.role];
+                       let userType = mockApis.userTypes[env.role];
 
-       let middlewares = [
-               (req, res, next) => {
-               res.cookie(mockApis.cookie.userIdSuffix, req.headers[mockApis.cookie.userIdSuffix] || userType.userId);
-       res.cookie(mockApis.cookie.userEmail, req.headers[mockApis.cookie.userEmail] || userType.email);
-       res.cookie(mockApis.cookie.userFirstName, req.headers[mockApis.cookie.userFirstName] || userType.firstName);
-       res.cookie(mockApis.cookie.userLastName, req.headers[mockApis.cookie.userLastName] || userType.lastName);
-       next();
-}
-];
+                       let middlewares = [
+                               (req, res, next) => {
+                                       res.cookie(mockApis.cookie.userIdSuffix, req.headers[mockApis.cookie.userIdSuffix] || userType.userId);
+                                       res.cookie(mockApis.cookie.userEmail, req.headers[mockApis.cookie.userEmail] || userType.email);
+                                       res.cookie(mockApis.cookie.userFirstName, req.headers[mockApis.cookie.userFirstName] || userType.firstName);
+                                       res.cookie(mockApis.cookie.userLastName, req.headers[mockApis.cookie.userLastName] || userType.lastName);
+                                       next();
+                               }
+                       ];
 
-       // Redirect all '/sdc1/feProxy/rest' to feHost
-       middlewares.push(
-               proxy(['/sdc1/feProxy/rest'],{
-                       target: 'http://' + loclahost + ':' + fePort,
-                       changeOrigin: true,
-                       secure: false
-               }));
+                       // Redirect all '/sdc1/feProxy/rest' to feHost
+                       middlewares.push(
+                               proxy(['/sdc1/feProxy/rest'], {
+                                       target: 'http://' + localhost + ':' + fePort,
+                                       changeOrigin: true,
+                                       secure: false
+                               }));
 
-       // Redirect all '/sdc1/rest' to feHost
-       middlewares.push(
-               proxy(['/sdc1/rest'],{
-                       target: 'http://' + loclahost + ':' + fePort,
-                       changeOrigin: true,
-                       secure: false
-               }));
+                       // Redirect all '/sdc1/rest' to feHost
+                       middlewares.push(
+                               proxy(['/sdc1/rest'],{
+                                       target: 'http://' + localhost + ':' + fePort,
+                                       changeOrigin: true,
+                                       secure: false
+                               }));
 
-       // Redirect dcae urls to feHost
-       middlewares.push(
-               proxy(['/dcae','/sdc1/feProxy/dcae-api'],{
-                       target: 'http://' + loclahost + ':' + fePort,
-                       changeOrigin: true,
-                       secure: false,
-                       onProxyRes: (proxyRes, req, res) => {
-                       let setCookie = proxyRes.headers['set-cookie'];
-       if (setCookie) {
-               setCookie[0] = setCookie[0].replace(/\bSecure\b(; )?/, '');
-       }
-}
-}));
+                       // Redirect dcae urls to feHost
+                       middlewares.push(
+                               proxy(['/dcae','/sdc1/feProxy/dcae-api'], {
+                                       target: 'http://' + localhost + ':' + fePort,
+                                       changeOrigin: true,
+                                       secure: false,
+                                       onProxyRes: (proxyRes, req, res) => {
+                                               let setCookie = proxyRes.headers['set-cookie'];
+                                               if (setCookie) {
+                                                       setCookie[0] = setCookie[0].replace(/\bSecure\b(; )?/, '');
+                                               }
+                                       }
+                       }));
 
-       // Redirect onboarding urls to feHost
-       middlewares.push(
-               proxy(['/onboarding','/sdc1/feProxy/onboarding-api'],{
-                       target: 'http://' + loclahost + ':' + fePort,
-                       changeOrigin: true,
-                       secure: false,
-                       onProxyRes: (proxyRes, req, res) => {
-                       let setCookie = proxyRes.headers['set-cookie'];
-       if (setCookie) {
-               setCookie[0] = setCookie[0].replace(/\bSecure\b(; )?/, '');
-       }
-}
-}));
+                       // Redirect onboarding urls to feHost
+                       middlewares.push(
+                               proxy(['/onboarding', '/sdc1/feProxy/onboarding-api'], {
+                                       target: 'http://' + localhost + ':' + fePort,
+                                       changeOrigin: true,
+                                       secure: false,
+                                       onProxyRes: (proxyRes, req, res) => {
+                                               let setCookie = proxyRes.headers['set-cookie'];
+                                               if (setCookie) {
+                                                       setCookie[0] = setCookie[0].replace(/\bSecure\b(; )?/, '');
+                                               }
+                                       }
+                       }));
 
-       server.use(middlewares);
-}
-};
+                       // Redirect workflow urls to feHost
+                       middlewares.push(
+                               proxy(['/sdc1/feProxy/wf', '/wf'], {
+                                       target: 'http://' + localhost + ':' + fePort,
+                                       changeOrigin: true,
+                                       secure: false,
+                                       onProxyRes: (proxyRes, req, res) => {
+                                               let setCookie = proxyRes.headers['set-cookie'];
+                                               if (setCookie) {
+                                                       setCookie[0] = setCookie[0].replace(/\bSecure\b(; )?/, '');
+                                               }
+                                       }
+                       }));
+
+                       server.use(middlewares);
+               }
+       };
 
        return ServerConfig;
 }