aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArielk <Ariel.Kenan@amdocs.com>2018-07-31 12:59:36 +0300
committerAvi Gaffa <avi.gaffa@amdocs.com>2018-08-02 08:56:34 +0000
commiteaaf8019188ad99ad2b76e43519c7dae9f4ac592 (patch)
tree3f42e4ea4bee6c2735395f61bb9f6f1623f64570
parentdecd2dff3b5b8aff53be52c825e45186d5c16e99 (diff)
Enhance operations to associate workflows
Change-Id: Iacf74ee333a3bc2e76e764c28ae660322bc9e6e4 Issue-ID: SDC-1535 Signed-off-by: Arielk <Ariel.Kenan@amdocs.com>
-rw-r--r--catalog-ui/configurations/dev.js2
-rw-r--r--catalog-ui/configurations/prod.js2
-rw-r--r--catalog-ui/src/app/models/operation.ts40
-rw-r--r--catalog-ui/src/app/ng2/app.module.ts6
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts42
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html91
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.less48
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts161
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.html42
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.less18
-rw-r--r--catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.ts19
-rw-r--r--catalog-ui/src/app/ng2/services/workflow.service.ts52
-rw-r--r--catalog-ui/src/app/utils/common-utils.ts14
-rw-r--r--catalog-ui/src/assets/languages/en_US.json3
-rw-r--r--catalog-ui/webpack.server.js122
15 files changed, 511 insertions, 151 deletions
diff --git a/catalog-ui/configurations/dev.js b/catalog-ui/configurations/dev.js
index 7e67dbbcb3..1dc8c81c3e 100644
--- a/catalog-ui/configurations/dev.js
+++ b/catalog-ui/configurations/dev.js
@@ -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",
diff --git a/catalog-ui/configurations/prod.js b/catalog-ui/configurations/prod.js
index adbd650378..cd94f53c13 100644
--- a/catalog-ui/configurations/prod.js
+++ b/catalog-ui/configurations/prod.js
@@ -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",
diff --git a/catalog-ui/src/app/models/operation.ts b/catalog-ui/src/app/models/operation.ts
index 55fcd82320..2a5298c3b0 100644
--- a/catalog-ui/src/app/models/operation.ts
+++ b/catalog-ui/src/app/models/operation.ts
@@ -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
};
diff --git a/catalog-ui/src/app/ng2/app.module.ts b/catalog-ui/src/app/ng2/app.module.ts
index c949a73248..7a845ef159 100644
--- a/catalog-ui/src/app/ng2/app.module.ts
+++ b/catalog-ui/src/app/ng2/app.module.ts
@@ -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,
diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts b/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts
index c58e1de135..010a1f9dda 100644
--- a/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts
+++ b/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts
@@ -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);
+ }
});
}
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 9e47cd5cef..c0a6966ceb 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
@@ -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" >
@@ -24,33 +25,85 @@
</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>
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 289dd5b452..f962bc2dca 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
@@ -48,19 +48,59 @@
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;
}
}
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 cc7b5feaf3..8d26055feb 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
@@ -1,68 +1,179 @@
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();
}
}
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 86d7628c17..2a72177621 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,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"
diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.less b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.less
index 9abd7c7681..8795d22e8d 100644
--- a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.less
+++ b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.less
@@ -5,7 +5,7 @@
align-items: center;
justify-content: center;
- .delete-item-icon {
+ .delete-btn {
&:hover {
cursor: pointer;
}
@@ -14,16 +14,26 @@
.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;
+ }
+ }
}
diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.ts b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.ts
index 01e0629942..75d4fcf7d2 100644
--- a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.ts
+++ b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.ts
@@ -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
index 0000000000..7e596e1eda
--- /dev/null
+++ b/catalog-ui/src/app/ng2/services/workflow.service.ts
@@ -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();
+ });
+ }
+
+}
diff --git a/catalog-ui/src/app/utils/common-utils.ts b/catalog-ui/src/app/utils/common-utils.ts
index d215183fa9..0c6a8b6a54 100644
--- a/catalog-ui/src/app/utils/common-utils.ts
+++ b/catalog-ui/src/app/utils/common-utils.ts
@@ -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);
}
diff --git a/catalog-ui/src/assets/languages/en_US.json b/catalog-ui/src/assets/languages/en_US.json
index 612d14e707..64be28506b 100644
--- a/catalog-ui/src/assets/languages/en_US.json
+++ b/catalog-ui/src/assets/languages/en_US.json
@@ -451,6 +451,9 @@
"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.",
diff --git a/catalog-ui/webpack.server.js b/catalog-ui/webpack.server.js
index a0f6fb1a24..b8821cd9d1 100644
--- a/catalog-ui/webpack.server.js
+++ b/catalog-ui/webpack.server.js
@@ -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;
}