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] = {};
343 this.isLoading = true;
344 this.validityChanged();
345 return this.workflowServiceNg2.getWorkflowVersions(this.operation.workflowId).subscribe((versions: Array<any>) => {
346 this.isLoading = false;
348 this.workflowVersions = _.map(
350 versions, version => version.state === this.workflowServiceNg2.VERSION_STATE_CERTIFIED
351 ).sort((a, b) => a.name.localeCompare(b.name)),
353 if (!this.assignInputParameters[this.operation.workflowId][version.id] && version.id !== selectedVersionId) {
354 this.assignInputParameters[this.operation.workflowId][version.id] = _.map(version.inputs, (input: any) => {
355 return new OperationParameter({...input, type: input.type.toLowerCase(), required: Boolean(input.mandatory)});
357 .sort((a, b) => a.name.localeCompare(b.name));
359 this.assignOutputParameters[this.operation.workflowId][version.id] = _.map(version.outputs, (output: any) => {
360 return new OperationParameter({...output, type: output.type.toLowerCase(), required: Boolean(output.mandatory)});
362 .sort((a, b) => a.name.localeCompare(b.name));
364 return new DropdownValue(version.id, `V ${version.name}`);
367 if (!selectedVersionId && this.workflowVersions.length) {
368 this.operation.workflowVersionId = _.last(this.workflowVersions).value;
371 this.changeWorkflowVersion(new DropDownOption(this.operation.workflowVersionId));
372 this.validityChanged();
377 changeWorkflowVersion(versionId: DropDownOption) {
379 if (_.isUndefined(versionId) || !this.workflowIsOnline) {
383 this.operation.workflowVersionId = versionId.value;
384 this.inputParameters = this.assignInputParameters[this.operation.workflowId][this.operation.workflowVersionId];
385 this.outputParameters = this.assignOutputParameters[this.operation.workflowId][this.operation.workflowVersionId];
387 this.validityChanged();
391 toggleAssociateWorkflow(type: DropDownOption) {
393 if (_.isUndefined(type)) {
397 this.operation.workflowAssociationType = type.value;
398 this.workflowAssociationType = this.operation.workflowAssociationType;
400 if (!this.isUsingExistingWF()) {
401 this.inputParameters = this.noAssignInputParameters;
402 this.outputParameters = this.noAssignOutputParameters;
404 if (!this.operation.workflowId || !this.operation.workflowVersionId) {
405 this.inputParameters = [];
406 this.outputParameters = [];
408 this.inputParameters = this.assignInputParameters[this.operation.workflowId][this.operation.workflowVersionId];
409 this.outputParameters = this.assignOutputParameters[this.operation.workflowId][this.operation.workflowVersionId];
414 this.validityChanged();
418 onChangeArtifactFile(e: any) {
419 const file = e.target.files && e.target.files[0];
420 this.operation.artifactFileName = file && file.name;
422 if (!this.operation.artifactFileName) {
423 this.operation.artifactData = null;
424 this.validityChanged();
428 const reader = new FileReader();
429 reader.onloadend = () => {
430 this.isLoading = false;
431 const result = <String>reader.result;
432 this.operation.artifactData = result.substring(result.indexOf(',') + 1);
433 this.validityChanged();
436 this.isLoading = true;
437 reader.readAsDataURL(file);
440 tabChanged = (event) => {
442 this.currentTab = event.title;
449 switch (this.currentTab) {
450 case this.TYPE_INPUT:
451 this.tableParameters = this.inputParameters;
453 case this.TYPE_OUTPUT:
454 this.tableParameters = this.outputParameters;
460 addParam(param?: OperationParameter): void {
461 this.tableParameters.push(new OperationParameter(param || {required: false}));
462 this.validityChanged();
465 canAdd = (): boolean => {
468 if (this.currentTab === this.TYPE_INPUT) {
469 _.forEach(this.inputParameters, param => {
470 if (!param.name || !param.inputId) {
475 _.forEach(this.outputParameters, param => {
476 if (!param.name || !param.type) {
486 isParamsValid = (): boolean => {
489 _.forEach(this.inputParameters, param => {
490 if (!param.name || !param.inputId) {
494 _.forEach(this.outputParameters, param => {
495 if (!param.name || !param.type) {
504 onRemoveParam = (param: OperationParameter): void => {
505 let index = _.indexOf(this.tableParameters, param);
506 this.tableParameters.splice(index, 1);
507 this.validityChanged();
510 createParamLists = () => {
511 this.operation.createInputsList(this.inputParameters);
512 this.operation.createOutputsList(this.outputParameters);
515 isUsingExistingWF = (operation?: OperationModel): boolean => {
516 operation = operation || this.operation;
517 return operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXISTING;
520 isUsingExternalWF = (operation?: OperationModel): boolean => {
521 operation = operation || this.operation;
522 return operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL;
525 shouldCreateWF = (operation?: OperationModel): boolean => {
526 operation = operation || this.operation;
527 return operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.NEW;
530 checkFormValidForSubmit = (): boolean => {
531 return this.operation.name &&
532 (!this.isUsingExistingWF() || this.operation.workflowVersionId) &&
533 this.isParamsValid();
536 validityChanged = () => {
537 let validState = this.checkFormValidForSubmit();
538 this.validityChangedCallback(validState);
541 getSelectedDropdown(options: DropdownValue[], selectedValue: string): DropdownValue {
542 const selectedDropdown = _.find(options, (option) => option.value === selectedValue);
543 return selectedDropdown || this.toDropDownOption(null);
546 toDropDownOption(val: string) {
547 return { value : val, label: val };