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 if (this.enableWorkflowAssociation && inputOperation.workflowVersionId && this.isUsingExistingWF(inputOperation)) {
215 this.assignInputParameters[this.operation.workflowId] = {[inputOperation.workflowVersionId]: []};
216 this.assignOutputParameters[this.operation.workflowId] = {[inputOperation.workflowVersionId]: []};
217 this.inputParameters = this.assignInputParameters[this.operation.workflowId][this.operation.workflowVersionId];
218 this.outputParameters = this.assignOutputParameters[this.operation.workflowId][this.operation.workflowVersionId];
220 const sub = this.onSelectWorkflow(new DropDownOption(inputOperation.workflowId), inputOperation.workflowVersionId);
224 this.operation.workflowVersionId = '-1';
225 setTimeout(() => this.operation.workflowVersionId = this.inputOperation.workflowVersionId);
231 this.inputParameters = this.noAssignInputParameters;
232 this.outputParameters = this.noAssignOutputParameters;
236 if (inputOperation.uniqueId) {
237 this.isEditMode = true;
243 filterCapabilities() {
244 this.componentCapabilities = _.filter(this.capabilities, (cap: Capability) => cap.properties);
247 buildParams = () => {
249 if (this.inputOperation.outputs) {
250 this.currentTab = this.TYPE_OUTPUT;
253 [...this.inputOperation.outputs.listToscaDataDefinition].sort((a, b) => a.name.localeCompare(b.name)),
254 (output: OperationParameter) => {
255 this.addParam({...output, required: Boolean(output.required)});
260 this.currentTab = this.TYPE_INPUT;
262 if (this.inputOperation.inputs) {
264 [...this.inputOperation.inputs.listToscaDataDefinition].sort((a, b) => a.name.localeCompare(b.name)),
265 (input: OperationParameter) => {
266 this.addParam({...input, required: Boolean(input.required)});
273 isInterfaceOther(): boolean {
274 return this.operation.interfaceType === this.INTERFACE_OTHER;
277 onSelectInterface(interf: IDropDownOption) {
278 if (interf && this.operation.interfaceType !== interf.value) {
279 this.operation.name = null;
281 this.operation.interfaceType = interf && interf.value;
282 this.operationNames = !this.operation.interfaceType ? [] : (
284 this.interfaceTypes[this.operation.interfaceType],
286 const curInterf = _.find(
288 interf => interf.type === this.operation.interfaceType
290 const existingOp = _.find(
291 curInterf && curInterf.operations || [],
292 op => op.name === name
294 const ddType = (existingOp && existingOp.uniqueId !== this.operation.uniqueId) ? DROPDOWN_OPTION_TYPE.HORIZONTAL_LINE : DROPDOWN_OPTION_TYPE.SIMPLE;
295 return new TypedDropDownOption(name, name, ddType);
299 if(this.operationNamesDropdown) {
300 this.operationNamesDropdown.allOptions = <IDropDownOption[]>this.operationNames;
302 this.validityChanged();
305 onSelectOperationName(name: IDropDownOption) {
307 this.operation.name = name.value;
309 this.validityChanged();
313 this.validityChanged();
316 get descriptionValue() {
317 return this.operation.description;
320 set descriptionValue(v) {
321 this.operation.description = v || null;
322 this.validityChanged();
325 onSelectWorkflow(workflowId: DropDownOption, selectedVersionId?: string): Subscription {
327 if (_.isUndefined(workflowId) || !this.workflowIsOnline) {
331 if (this.operation.workflowId === workflowId.value && !selectedVersionId) {
335 this.operation.workflowId = workflowId.value;
336 if (!this.assignInputParameters[this.operation.workflowId]) {
337 this.assignInputParameters[this.operation.workflowId] = {};
338 this.assignOutputParameters[this.operation.workflowId] = {};
340 this.operation.workflowName = workflowId.label;
341 if (!this.assignInputParameters[this.operation.workflowName]) {
342 this.assignInputParameters[this.operation.workflowName] = {};
343 this.assignOutputParameters[this.operation.workflowName] = {};
346 this.isLoading = true;
347 this.validityChanged();
348 return this.workflowServiceNg2.getWorkflowVersions(this.operation.workflowId).subscribe((versions: Array<any>) => {
349 this.isLoading = false;
351 this.workflowVersions = _.map(
353 versions, version => version.state === this.workflowServiceNg2.VERSION_STATE_CERTIFIED
354 ).sort((a, b) => a.name.localeCompare(b.name)),
356 if (!this.assignInputParameters[this.operation.workflowId][version.id] && version.id !== selectedVersionId) {
357 this.assignInputParameters[this.operation.workflowId][version.id] = _.map(version.inputs, (input: any) => {
358 return new OperationParameter({...input, type: input.type.toLowerCase(), required: Boolean(input.mandatory)});
360 .sort((a, b) => a.name.localeCompare(b.name));
362 this.assignOutputParameters[this.operation.workflowId][version.id] = _.map(version.outputs, (output: any) => {
363 return new OperationParameter({...output, type: output.type.toLowerCase(), required: Boolean(output.mandatory)});
365 .sort((a, b) => a.name.localeCompare(b.name));
367 return new DropdownValue(version.id, `V ${version.name}`);
370 if (!selectedVersionId && this.workflowVersions.length) {
371 this.operation.workflowVersionId = _.last(this.workflowVersions).value;
372 this.operation.workflowVersion = _.last(this.workflowVersions).label;
375 this.changeWorkflowVersion(new DropDownOption(this.operation.workflowVersionId));
376 this.validityChanged();
381 changeWorkflowVersion(versionId: DropDownOption) {
383 if (_.isUndefined(versionId) || !this.workflowIsOnline) {
387 this.operation.workflowVersionId = versionId.value;
388 this.inputParameters = this.assignInputParameters[this.operation.workflowId][this.operation.workflowVersionId];
389 this.outputParameters = this.assignOutputParameters[this.operation.workflowId][this.operation.workflowVersionId];
391 this.validityChanged();
395 toggleAssociateWorkflow(type: DropDownOption) {
397 if (_.isUndefined(type)) {
401 this.operation.workflowAssociationType = type.value;
402 this.workflowAssociationType = this.operation.workflowAssociationType;
404 if (!this.isUsingExistingWF()) {
405 this.inputParameters = this.noAssignInputParameters;
406 this.outputParameters = this.noAssignOutputParameters;
408 if (!this.operation.workflowId || !this.operation.workflowVersionId) {
409 this.inputParameters = [];
410 this.outputParameters = [];
412 this.inputParameters = this.assignInputParameters[this.operation.workflowId][this.operation.workflowVersionId];
413 this.outputParameters = this.assignOutputParameters[this.operation.workflowId][this.operation.workflowVersionId];
418 this.validityChanged();
422 onChangeArtifactFile(e: any) {
423 const file = e.target.files && e.target.files[0];
424 this.operation.artifactFileName = file && file.name;
426 if (!this.operation.artifactFileName) {
427 this.operation.artifactData = null;
428 this.validityChanged();
432 const reader = new FileReader();
433 reader.onloadend = () => {
434 this.isLoading = false;
435 const result = <String>reader.result;
436 this.operation.artifactData = result.substring(result.indexOf(',') + 1);
437 this.validityChanged();
440 this.isLoading = true;
441 reader.readAsDataURL(file);
444 tabChanged = (event) => {
446 this.currentTab = event.title;
453 switch (this.currentTab) {
454 case this.TYPE_INPUT:
455 this.tableParameters = this.inputParameters;
457 case this.TYPE_OUTPUT:
458 this.tableParameters = this.outputParameters;
464 addParam(param?: OperationParameter): void {
465 this.tableParameters.push(new OperationParameter(param || {required: false}));
466 this.validityChanged();
469 canAdd = (): boolean => {
472 if (this.currentTab === this.TYPE_INPUT) {
473 _.forEach(this.inputParameters, param => {
474 if (!param.name || !param.inputId) {
479 _.forEach(this.outputParameters, param => {
480 if (!param.name || !param.type) {
490 isParamsValid = (): boolean => {
493 _.forEach(this.inputParameters, param => {
494 if (!param.name || !param.inputId) {
498 _.forEach(this.outputParameters, param => {
499 if (!param.name || !param.type) {
508 onRemoveParam = (param: OperationParameter): void => {
509 let index = _.indexOf(this.tableParameters, param);
510 this.tableParameters.splice(index, 1);
511 this.validityChanged();
514 createParamLists = () => {
515 this.operation.createInputsList(this.inputParameters);
516 this.operation.createOutputsList(this.outputParameters);
519 isUsingExistingWF = (operation?: OperationModel): boolean => {
520 operation = operation || this.operation;
521 return operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXISTING;
524 isUsingExternalWF = (operation?: OperationModel): boolean => {
525 operation = operation || this.operation;
526 return operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL;
529 shouldCreateWF = (operation?: OperationModel): boolean => {
530 operation = operation || this.operation;
531 return operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.NEW;
534 checkFormValidForSubmit = (): boolean => {
535 return this.operation.name &&
536 (!this.isUsingExistingWF() || this.operation.workflowVersionId) &&
537 this.isParamsValid();
540 validityChanged = () => {
541 let validState = this.checkFormValidForSubmit();
542 this.validityChangedCallback(validState);
545 getSelectedDropdown(options: DropdownValue[], selectedValue: string): DropdownValue {
546 const selectedDropdown = _.find(options, (option) => option.value === selectedValue);
547 return selectedDropdown || this.toDropDownOption(null);
550 toDropDownOption(val: string) {
551 return { value : val, label: val };