1 import * as _ from "lodash";
2 import {Component, ViewChild} from '@angular/core';
4 import {Subscription} from "rxjs/Subscription";
6 import {TranslateService} from "app/ng2/shared/translator/translate.service";
7 import {WorkflowServiceNg2} from 'app/ng2/services/workflow.service';
13 WORKFLOW_ASSOCIATION_OPTIONS,
17 import { Tabs } from "app/ng2/components/ui/tabs/tabs.component";
18 import { DropdownValue } from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component";
19 import { IDropDownOption } from 'onap-ui-angular';
20 import { DropDownComponent } from "onap-ui-angular/dist/components";
21 import { DROPDOWN_OPTION_TYPE } from "app/utils/constants";
23 export class DropDownOption implements IDropDownOption {
27 constructor(value: string, label?: string) {
29 this.label = label || value;
33 class TypedDropDownOption extends DropDownOption {
36 constructor(value: string, label?: string, type?: string) {
42 export interface OperationCreatorInput {
43 allWorkflows: Array<any>,
44 inputOperation: OperationModel,
45 interfaces: Array<InterfaceModel>,
46 inputProperties: Array<InputBEModel>,
47 enableWorkflowAssociation: boolean,
49 interfaceTypes: { [interfaceType: string]: Array<string> },
50 validityChangedCallback: Function,
51 workflowIsOnline: boolean,
52 capabilities: Array<Capability>
56 selector: 'operation-creator',
57 templateUrl: './operation-creator.component.html',
58 styleUrls: ['./operation-creator.component.less'],
59 providers: [TranslateService]
62 export class OperationCreatorComponent implements OperationCreatorInput {
64 input: OperationCreatorInput;
65 inputOperation: OperationModel;
66 interfaces: Array<InterfaceModel>;
67 operation: OperationModel;
68 interfaceNames: Array<TypedDropDownOption> = [];
69 interfaceTypes: { [interfaceType: string]: Array<string> };
70 operationNames: Array<TypedDropDownOption> = [];
71 validityChangedCallback: Function;
72 capabilities: Array<Capability>;
74 allWorkflows: Array<any>;
75 workflows: Array<DropdownValue> = [];
76 workflowVersions: Array<DropdownValue> = [];
77 inputProperties: Array<InputBEModel> = [];
78 archivedWorkflowId: string = '&';
80 inputParameters: Array<OperationParameter> = [];
81 noAssignInputParameters: Array<OperationParameter> = [];
82 assignInputParameters: { [key: string]: { [key: string]: Array<OperationParameter>; }; } = {};
84 outputParameters: Array<OperationParameter> = [];
85 noAssignOutputParameters: Array<OperationParameter> = [];
86 assignOutputParameters: { [key: string]: { [key: string]: Array<OperationParameter>; }; } = {};
87 componentCapabilities: Array<Capability> = [];
89 tableParameters: Array<OperationParameter> = [];
90 operationOutputs: Array<OperationModel> = [];
92 associationOptions: Array<DropdownValue> = [];
93 workflowAssociationType: string;
95 enableWorkflowAssociation: boolean;
96 workflowIsOnline: boolean;
97 isEditMode: boolean = false;
98 isLoading: boolean = false;
101 propertyTooltipText: String;
103 TYPE_INPUT = 'Inputs';
104 TYPE_OUTPUT = 'Outputs';
106 INTERFACE_OTHER_HEADER = 'Local Interfaces';
107 INTERFACE_OTHER = 'Local';
109 @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
110 @ViewChild('operationNamesDropdown') operationNamesDropdown: DropDownComponent;
111 @ViewChild('workflowAssignmentDropdown') workflowAssignmentDropdown: DropDownComponent;
114 constructor(private workflowServiceNg2: WorkflowServiceNg2, private translateService: TranslateService) {
115 this.translateService.languageChangedObservable.subscribe(lang => {
116 this.propertyTooltipText = this.translateService.translate("OPERATION_PROPERTY_TOOLTIP_TEXT");
118 this.associationOptions = [
119 new DropDownOption(WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL, this.translateService.translate("EXTERNAL_WORKFLOW_ASSOCIATION")),
120 new DropDownOption(WORKFLOW_ASSOCIATION_OPTIONS.EXISTING, this.translateService.translate("EXISTING_WORKFLOW_ASSOCIATION")),
123 this.workflowAssociationType = this.operation.workflowAssociationType;
126 this.currentTab = this.TYPE_INPUT;
129 createInterfaceDropdown(type: string) {
131 const lastDot = label.lastIndexOf('.');
133 label = label.substr(lastDot + 1);
135 return new TypedDropDownOption(type, label);
139 this.interfaceNames = _.map(
140 _.keys(this.interfaceTypes),
141 type => this.createInterfaceDropdown(type)
143 this.interfaceNames.unshift(new TypedDropDownOption('Existing Interfaces', 'Existing Interfaces', DROPDOWN_OPTION_TYPE.HEADER));
144 this.interfaceNames = this.interfaceNames.concat([
145 new TypedDropDownOption(' ', ' ', DROPDOWN_OPTION_TYPE.HORIZONTAL_LINE),
146 new TypedDropDownOption(this.INTERFACE_OTHER_HEADER, this.INTERFACE_OTHER_HEADER, DROPDOWN_OPTION_TYPE.HEADER),
147 new TypedDropDownOption(this.INTERFACE_OTHER)
149 const inputOperation = this.inputOperation;
150 this.operation = new OperationModel(inputOperation || {});
152 this.operationOutputs = _.reduce(
154 (acc: Array<OperationModel>, interf) => [
158 op => op.uniqueId !== this.operation.uniqueId
163 if (this.enableWorkflowAssociation) {
164 if (this.workflowIsOnline) {
165 this.workflows = _.map(
169 if (workflow.archiving === this.workflowServiceNg2.WF_STATE_ACTIVE) {
172 if (workflow.archiving === this.workflowServiceNg2.WF_STATE_ARCHIVED &&
173 workflow.id === this.operation.workflowId) {
174 this.archivedWorkflowId = workflow.id;
180 (workflow: any) => new DropdownValue(workflow.id, workflow.name)
186 this.reconstructOperation();
187 this.filterCapabilities();
188 this.validityChanged();
193 if(this.workflowAssignmentDropdown){
194 this.workflowAssignmentDropdown.allOptions = this.associationOptions && this.associationOptions.length ?
195 this.associationOptions :
197 new DropDownOption(WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL, this.translateService.translate("EXTERNAL_WORKFLOW_ASSOCIATION")),
198 new DropDownOption(WORKFLOW_ASSOCIATION_OPTIONS.EXISTING, this.translateService.translate("EXISTING_WORKFLOW_ASSOCIATION")),
203 reconstructOperation = () => {
205 const buildAndUpdate = () => {
210 const inputOperation = this.inputOperation;
211 if (inputOperation) {
212 this.onSelectInterface(new DropDownOption(this.operation.interfaceType));
214 this.operation.artifactFileName = this.operation.artifactFileName || this.operation.implementation.artifactName;
216 if (this.enableWorkflowAssociation && inputOperation.workflowVersionId && this.isUsingExistingWF(inputOperation)) {
217 this.assignInputParameters[this.operation.workflowId] = {[inputOperation.workflowVersionId]: []};
218 this.assignOutputParameters[this.operation.workflowId] = {[inputOperation.workflowVersionId]: []};
219 this.inputParameters = this.assignInputParameters[this.operation.workflowId][this.operation.workflowVersionId];
220 this.outputParameters = this.assignOutputParameters[this.operation.workflowId][this.operation.workflowVersionId];
222 const sub = this.onSelectWorkflow(new DropDownOption(inputOperation.workflowId), inputOperation.workflowVersionId);
226 this.operation.workflowVersionId = '-1';
227 setTimeout(() => this.operation.workflowVersionId = this.inputOperation.workflowVersionId);
233 this.inputParameters = this.noAssignInputParameters;
234 this.outputParameters = this.noAssignOutputParameters;
238 if (inputOperation.uniqueId) {
239 this.isEditMode = true;
245 filterCapabilities() {
246 this.componentCapabilities = _.filter(this.capabilities, (cap: Capability) => cap.properties);
249 buildParams = () => {
251 if (this.inputOperation.outputs) {
252 this.currentTab = this.TYPE_OUTPUT;
255 [...this.inputOperation.outputs.listToscaDataDefinition].sort((a, b) => a.name.localeCompare(b.name)),
256 (output: OperationParameter) => {
257 this.addParam({...output, required: Boolean(output.required)});
262 this.currentTab = this.TYPE_INPUT;
264 if (this.inputOperation.inputs) {
266 [...this.inputOperation.inputs.listToscaDataDefinition].sort((a, b) => a.name.localeCompare(b.name)),
267 (input: OperationParameter) => {
268 this.addParam({...input, required: Boolean(input.required)});
275 isInterfaceOther(): boolean {
276 return this.operation.interfaceType === this.INTERFACE_OTHER;
279 onSelectInterface(interf: IDropDownOption) {
280 if (interf && this.operation.interfaceType !== interf.value) {
281 this.operation.name = null;
283 this.operation.interfaceType = interf && interf.value;
284 this.operationNames = !this.operation.interfaceType ? [] : (
286 this.interfaceTypes[this.operation.interfaceType],
288 const curInterf = _.find(
290 interf => interf.type === this.operation.interfaceType
292 const existingOp = _.find(
293 curInterf && curInterf.operations || [],
294 op => op.name === name
296 const ddType = (existingOp && existingOp.uniqueId !== this.operation.uniqueId) ? DROPDOWN_OPTION_TYPE.HORIZONTAL_LINE : DROPDOWN_OPTION_TYPE.SIMPLE;
297 return new TypedDropDownOption(name, name, ddType);
301 if(this.operationNamesDropdown) {
302 this.operationNamesDropdown.allOptions = <IDropDownOption[]>this.operationNames;
304 this.validityChanged();
307 onSelectOperationName(name: IDropDownOption) {
309 this.operation.name = name.value;
311 this.validityChanged();
315 this.validityChanged();
318 get descriptionValue() {
319 return this.operation.description;
322 set descriptionValue(v) {
323 this.operation.description = v || null;
324 this.validityChanged();
327 onSelectWorkflow(workflowId: DropDownOption, selectedVersionId?: string): Subscription {
329 if (_.isUndefined(workflowId) || !this.workflowIsOnline) {
333 if (this.operation.workflowId === workflowId.value && !selectedVersionId) {
337 this.operation.workflowId = workflowId.value;
338 if (!this.assignInputParameters[this.operation.workflowId]) {
339 this.assignInputParameters[this.operation.workflowId] = {};
340 this.assignOutputParameters[this.operation.workflowId] = {};
342 this.operation.workflowName = workflowId.label;
343 if (!this.assignInputParameters[this.operation.workflowName]) {
344 this.assignInputParameters[this.operation.workflowName] = {};
345 this.assignOutputParameters[this.operation.workflowName] = {};
348 this.isLoading = true;
349 this.validityChanged();
350 return this.workflowServiceNg2.getWorkflowVersions(this.operation.workflowId).subscribe((versions: Array<any>) => {
351 this.isLoading = false;
353 this.workflowVersions = _.map(
355 versions, version => version.state === this.workflowServiceNg2.VERSION_STATE_CERTIFIED
356 ).sort((a, b) => a.name.localeCompare(b.name)),
358 if (!this.assignInputParameters[this.operation.workflowId][version.id] && version.id !== selectedVersionId) {
359 this.assignInputParameters[this.operation.workflowId][version.id] = _.map(version.inputs, (input: any) => {
360 return new OperationParameter({...input, type: input.type.toLowerCase(), required: Boolean(input.mandatory)});
362 .sort((a, b) => a.name.localeCompare(b.name));
364 this.assignOutputParameters[this.operation.workflowId][version.id] = _.map(version.outputs, (output: any) => {
365 return new OperationParameter({...output, type: output.type.toLowerCase(), required: Boolean(output.mandatory)});
367 .sort((a, b) => a.name.localeCompare(b.name));
369 return new DropdownValue(version.id, `V ${version.name}`);
372 if (!selectedVersionId && this.workflowVersions.length) {
373 this.operation.workflowVersionId = _.last(this.workflowVersions).value;
374 this.operation.workflowVersion = _.last(this.workflowVersions).label;
377 this.changeWorkflowVersion(new DropDownOption(this.operation.workflowVersionId));
378 this.validityChanged();
383 changeWorkflowVersion(versionId: DropDownOption) {
385 if (_.isUndefined(versionId) || !this.workflowIsOnline) {
389 this.operation.workflowVersionId = versionId.value;
390 this.inputParameters = this.assignInputParameters[this.operation.workflowId][this.operation.workflowVersionId];
391 this.outputParameters = this.assignOutputParameters[this.operation.workflowId][this.operation.workflowVersionId];
393 this.validityChanged();
397 toggleAssociateWorkflow(type: DropDownOption) {
399 if (_.isUndefined(type)) {
403 this.operation.workflowAssociationType = type.value;
404 this.workflowAssociationType = this.operation.workflowAssociationType;
406 if (!this.isUsingExistingWF()) {
407 this.inputParameters = this.noAssignInputParameters;
408 this.outputParameters = this.noAssignOutputParameters;
410 if (!this.operation.workflowId || !this.operation.workflowVersionId) {
411 this.inputParameters = [];
412 this.outputParameters = [];
414 this.inputParameters = this.assignInputParameters[this.operation.workflowId][this.operation.workflowVersionId];
415 this.outputParameters = this.assignOutputParameters[this.operation.workflowId][this.operation.workflowVersionId];
420 this.validityChanged();
424 onChangeArtifactFile(e: any) {
425 const file = e.target.files && e.target.files[0];
426 this.operation.artifactFileName = file && file.name;
428 if (!this.operation.artifactFileName) {
429 this.operation.artifactData = null;
430 this.validityChanged();
434 const reader = new FileReader();
435 reader.onloadend = () => {
436 this.isLoading = false;
437 const result = <String>reader.result;
438 this.operation.artifactData = result.substring(result.indexOf(',') + 1);
439 this.validityChanged();
442 this.isLoading = true;
443 reader.readAsDataURL(file);
446 tabChanged = (event) => {
448 this.currentTab = event.title;
455 switch (this.currentTab) {
456 case this.TYPE_INPUT:
457 this.tableParameters = this.inputParameters;
459 case this.TYPE_OUTPUT:
460 this.tableParameters = this.outputParameters;
466 addParam(param?: OperationParameter): void {
467 this.tableParameters.push(new OperationParameter(param || {required: false}));
468 this.validityChanged();
471 canAdd = (): boolean => {
474 if (this.currentTab === this.TYPE_INPUT) {
475 _.forEach(this.inputParameters, param => {
476 if (!param.name || !param.inputId) {
481 _.forEach(this.outputParameters, param => {
482 if (!param.name || !param.type) {
492 isParamsValid = (): boolean => {
495 _.forEach(this.inputParameters, param => {
496 if (!param.name || !param.inputId) {
500 _.forEach(this.outputParameters, param => {
501 if (!param.name || !param.type) {
510 onRemoveParam = (param: OperationParameter): void => {
511 let index = _.indexOf(this.tableParameters, param);
512 this.tableParameters.splice(index, 1);
513 this.validityChanged();
516 createParamLists = () => {
517 this.operation.createInputsList(this.inputParameters);
518 this.operation.createOutputsList(this.outputParameters);
521 isUsingExistingWF = (operation?: OperationModel): boolean => {
522 operation = operation || this.operation;
523 return operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXISTING;
526 isUsingExternalWF = (operation?: OperationModel): boolean => {
527 operation = operation || this.operation;
528 return operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL;
531 shouldCreateWF = (operation?: OperationModel): boolean => {
532 operation = operation || this.operation;
533 return operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.NEW;
536 checkFormValidForSubmit = (): boolean => {
537 return this.operation.name &&
538 (!this.isUsingExistingWF() || this.operation.workflowVersionId) &&
539 this.isParamsValid();
542 validityChanged = () => {
543 let validState = this.checkFormValidForSubmit();
544 this.validityChangedCallback(validState);
547 getSelectedDropdown(options: DropdownValue[], selectedValue: string): DropdownValue {
548 const selectedDropdown = _.find(options, (option) => option.value === selectedValue);
549 return selectedDropdown || this.toDropDownOption(null);
552 toDropDownOption(val: string) {
553 return { value : val, label: val };