b04e89f2150535dfd5ff470c0abe26bb2137d11e
[ccsdk/cds.git] /
1 import {Component, OnInit} from '@angular/core';
2 import {InputActionAttribute, OutputActionAttribute} from './models/InputActionAttribute';
3 import {DesignerStore} from '../designer.store';
4 import {DesignerDashboardState} from '../model/designer.dashboard.state';
5 import {Action} from './models/Action';
6 import {FunctionsStore} from '../functions.store';
7 import {FunctionsState} from '../model/functions.state';
8 import {PackageCreationStore} from '../../package-creation/package-creation.store';
9 import {CBAPackage} from '../../package-creation/mapping-models/CBAPacakge.model';
10
11 @Component({
12     selector: 'app-action-attributes',
13     templateUrl: './action-attributes.component.html',
14     styleUrls: ['./action-attributes.component.css']
15 })
16 export class ActionAttributesComponent implements OnInit {
17
18     inputs = [];
19     outputs = [];
20     newInputs = [];
21     newOutputs = [];
22     actionAttributesSideBar: boolean;
23     inputActionAttribute = new InputActionAttribute();
24     outputActionAttribute = new OutputActionAttribute();
25     isInputOtherType: boolean;
26     isOutputOtherType: boolean;
27     outputOtherType = '';
28     inputOtherType = '';
29     actionName = '';
30     designerState: DesignerDashboardState;
31     isFunctionAttributeActive = false;
32     functions: FunctionsState;
33     steps: string[];
34     suggestedInputs: string[] = [];
35     suggestedOutputs: string[] = [];
36
37     tempInputs: string[] = [];
38     tempOutputs: string[] = [];
39     currentInterfaceName: string;
40     functionAndAttributesInput: Map<string, string[]> = new Map<string, string[]>();
41     private currentTargetFunctionName: any;
42     private functionAndAttributesOutput: Map<string, string[]> = new Map<string, string[]>();
43     suggestedAttributes: string[] = [];
44     selectedFunctionName = '';
45     selectedAttributeName = '';
46     isNotComponentResourceResolution = true;
47     currentArtifacts: string[] = [];
48     isParametersHidden = true;
49     cbaPackage: CBAPackage;
50     suggestedMappingParameters: string[] = [];
51     selectedParameterList: string[] = [];
52     currentSuggestedArtifact: string;
53     suggestedDeletedInput: any = {};
54     suggestedEditedAttribute: any = {};
55
56     constructor(private designerStore: DesignerStore,
57                 private functionsStore: FunctionsStore,
58                 private packageCreationStore: PackageCreationStore) {
59
60     }
61
62     ngOnInit() {
63         console.log('is paramters hidden' + this.isParametersHidden);
64         console.log('is artifacts hidden' + this.isNotComponentResourceResolution);
65         this.designerStore.state$.subscribe(designerState => {
66             this.designerState = designerState;
67             if (this.designerState && this.designerState.actionName) {
68                 this.actionName = this.designerState.actionName;
69                 console.log(this.actionName);
70                 const action = this.designerState.template.workflows[this.actionName] as Action;
71                 if (action.steps) {
72                     const steps = Object.keys(action.steps);
73                     this.isFunctionAttributeActive = steps && steps.length > 0;
74                     this.steps = steps;
75                     this.suggestedOutputs = [];
76                     this.suggestedInputs = [];
77                 }
78                 this.inputs = [];
79                 if (action.inputs) {
80                     const namesOfInput = Object.keys(action.inputs);
81                     this.inputs = this.extractFields(namesOfInput, action.inputs);
82                 }
83                 this.outputs = [];
84                 if (action.outputs) {
85                     const namesOfOutput = Object.keys(action.outputs);
86                     this.outputs = this.extractFields(namesOfOutput, action.outputs);
87                 }
88             }
89         });
90
91         this.functionsStore.state$.subscribe(functions => {
92             this.functions = functions;
93         });
94
95         this.packageCreationStore.state$
96             .subscribe(cbaPackage => {
97                 this.cbaPackage = cbaPackage;
98
99             });
100     }
101
102
103     private extractFields(namesOfOutput: string[], container: {}) {
104         const fields = [];
105         for (const nameOutput of namesOfOutput) {
106             const fieldAttribute = new OutputActionAttribute();
107             fieldAttribute.name = nameOutput;
108             fieldAttribute.description = container[nameOutput].description;
109             fieldAttribute.required = container[nameOutput].required;
110             fieldAttribute.type = container[nameOutput].type;
111             fieldAttribute.value = container[nameOutput].value;
112             console.log(fieldAttribute.value);
113             const insertedOutputActionAttribute = Object.assign({}, fieldAttribute);
114             fields.push(insertedOutputActionAttribute);
115         }
116         return fields;
117     }
118
119     addInput(input: InputActionAttribute) {
120         console.log(input);
121         if (input && input.type && input.name) {
122             const insertedInputActionAttribute = Object.assign({}, input);
123             if (!this.newInputs.some(obj => obj.name === input.name)) {
124                 this.newInputs.push(insertedInputActionAttribute);
125             }
126         }
127     }
128
129     addOutput(output: OutputActionAttribute) {
130         console.log(output);
131         if (output && output.type && output.name) {
132             const insertedOutputActionAttribute = Object.assign({}, output);
133             this.newOutputs.push(insertedOutputActionAttribute);
134         }
135     }
136
137     setInputType(type: string) {
138         this.inputActionAttribute.type = type;
139         this.isInputOtherType = this.checkIfTypeIsOther(type);
140     }
141
142     setInputRequired(isRequired) {
143         this.inputActionAttribute.required = isRequired;
144     }
145
146     setOutputRequired(isRequired) {
147         this.outputActionAttribute.required = isRequired;
148     }
149
150     setOutputType(type: string) {
151         this.outputActionAttribute.type = type;
152         this.isOutputOtherType = this.checkIfTypeIsOther(type);
153         console.log(this.outputActionAttribute.type , this.isOutputOtherType , this.outputOtherType);
154     }
155
156     checkIfTypeIsOther(type) {
157         return type.includes('Other');
158     }
159
160     submitAttributes() {
161         console.log(this.getValue());
162         this.addInput(this.inputActionAttribute);
163         if (this.selectedFunctionName && this.selectedAttributeName) {
164             console.log(this.getValue());
165             this.outputActionAttribute.value =
166                 this.getValue();
167         }
168         if (this.isOutputOtherType) {
169             this.outputActionAttribute.type  = this.outputOtherType;
170         }
171         this.addOutput(this.outputActionAttribute);
172         this.clearFormInputs();
173         this.storeOutputs(this.newOutputs);
174         this.storeInputs((this.newInputs));
175         this.newInputs.forEach(input => {
176             if (!this.inputs.includes(input.name)) {
177                 this.inputs.push(input);
178             }
179         });
180
181         this.newOutputs.forEach(output => {
182             if (!this.outputs.includes(output)) {
183                 this.outputs.push(output);
184             }
185         });
186         this.newInputs = [];
187         this.newOutputs = [];
188     }
189
190     private getValue() {
191         let value = '["' + this.selectedFunctionName + '", "' + '","' + this.selectedAttributeName;
192
193         if (!this.isParametersHidden) {
194             let currentSelected = '';
195             for (const selectedParameter of this.selectedParameterList) {
196                 currentSelected += '"' + selectedParameter + '",';
197             }
198             value += '","' + this.currentSuggestedArtifact + '",'
199                 + currentSelected.substr(0, currentSelected.length - 2) + '';
200         } else if (!this.isNotComponentResourceResolution && this.currentSuggestedArtifact) {
201             value += '","' + this.currentSuggestedArtifact + '';
202
203         }
204
205         return value += '"]';
206     }
207
208     public clearFormInputs() {
209         console.log('trying to clear ');
210         this.inputActionAttribute = new InputActionAttribute();
211         this.outputActionAttribute = new OutputActionAttribute();
212         this.outputOtherType = '';
213         this.inputOtherType = '';
214     }
215
216     private storeInputs(InputActionAttributes: InputActionAttribute[]) {
217
218         let inputs = '';
219         InputActionAttributes.forEach(input => {
220             inputs += this.appendAttributes(input);
221             console.log(inputs);
222         });
223         if (inputs.length > 0) {
224             this.writeAttribute(inputs, 'inputs');
225         }
226     }
227
228     private storeOutputs(OutputActionAttributes: OutputActionAttribute[]) {
229         let outputs = '';
230         OutputActionAttributes.forEach(output => {
231             outputs += this.appendOutputAttributes(output);
232         });
233         if (outputs.length > 0) {
234             this.writeAttribute(outputs, 'outputs');
235         }
236
237     }
238
239     private appendAttributes(inputActionAttribute: InputActionAttribute) {
240         const entrySchema: string = this.getEntrySchema(inputActionAttribute);
241         const input = '"' + inputActionAttribute.name + '" : {\n' +
242             '            "required" : ' + inputActionAttribute.required + ',\n' +
243             '            "type" : "' + inputActionAttribute.type + '",\n' +
244             '            "description" : "' + inputActionAttribute.description + '"';
245         return input + entrySchema;
246     }
247
248     private getEntrySchema(inputActionAttribute: InputActionAttribute) {
249         return inputActionAttribute.type.includes('list') ?
250             ',\n\t' + '"entry_schema" : {\n' +
251             '              "type" : "string"\n' +
252             '            }\n},'
253             :
254             '\n },';
255     }
256
257     setInputAndOutputs(targetName) {
258         console.log(targetName);
259         const nodeTemplate = this.designerState.template.node_templates[targetName];
260         console.log(this.designerState.template.node_templates);
261         console.log(nodeTemplate);
262         /* tslint:disable:no-string-literal */
263         console.log(nodeTemplate['type']);
264         this.functions.serverFunctions
265             /* tslint:disable:no-string-literal */
266             .filter(currentFunction => currentFunction.modelName.includes(nodeTemplate['type']))
267             .forEach(currentFunction => {
268                 console.log(currentFunction);
269                 /* tslint:disable:no-string-literal */
270                 if (currentFunction['definition'] && currentFunction['definition']['interfaces']) {
271                     const interfaces = Object.keys(currentFunction['definition']['interfaces']);
272                     if (interfaces && interfaces.length > 0) {
273                         const interfaceName = interfaces[0];
274                         console.log(interfaceName);
275                         this.currentInterfaceName = interfaceName;
276
277                         if (!this.functionAndAttributesInput.has(targetName)) {
278                             this.currentTargetFunctionName = targetName;
279                             this.functionAndAttributesInput.set(targetName, []);
280                         }
281
282                         if (!this.functionAndAttributesOutput.has(targetName)) {
283                             this.currentTargetFunctionName = targetName;
284                             this.functionAndAttributesOutput.set(targetName, []);
285                         }
286
287                         if (nodeTemplate['interfaces'] &&
288                             nodeTemplate['interfaces'][interfaceName]['operations'] &&
289                             nodeTemplate['interfaces'][interfaceName]['operations']['process']
290                         ) {
291                             console.log('here');
292                             if (nodeTemplate['interfaces'][interfaceName]['operations']['process']['inputs']) {
293                                 /* tslint:disable:no-string-literal */
294                                 this.suggestedInputs = Object.keys(nodeTemplate['interfaces']
295                                     [interfaceName]['operations']['process']['inputs']);
296                                 this.filterTwoCollections(this.suggestedInputs, this.inputs);
297
298                             }
299                             if (nodeTemplate['interfaces'][interfaceName]['operations']['process']['outputs']) {
300                                 /* tslint:disable:no-string-literal */
301                                 this.suggestedOutputs = Object.keys(nodeTemplate['interfaces']
302                                     [interfaceName]['operations']['process']['outputs']);
303                                 this.filterTwoCollections(this.suggestedOutputs, this.outputs);
304                             }
305
306                         }
307                     }
308                 }
309             });
310         console.log(nodeTemplate);
311     }
312
313     private filterTwoCollections(suggestedInputs: string[], inputs: any[]) {
314         inputs.forEach(input => {
315             if (suggestedInputs.includes(input.name)) {
316                 this.deleteAttribute(suggestedInputs, input.name);
317             }
318         });
319     }
320
321     printSomethings() {
322         this.setInputAndOutputs(
323             this.designerState.template.workflows[this.actionName]['steps'][this.steps[0]]['target']
324         );
325     }
326
327     addTempInput(suggestedInput: string) {
328         this.addAttribute(this.tempInputs, suggestedInput);
329         this.deleteAttribute(this.suggestedInputs, suggestedInput);
330         this.addAttribute(this.functionAndAttributesInput.get(this.currentTargetFunctionName), suggestedInput);
331     }
332
333     addTempOutput(suggestedOutput: string) {
334         this.addAttribute(this.tempOutputs, suggestedOutput);
335         this.deleteAttribute(this.suggestedOutputs, suggestedOutput);
336         this.addAttribute(this.functionAndAttributesOutput.get(this.currentTargetFunctionName), suggestedOutput);
337     }
338
339     deleteAttribute(container: string[], suggestedAttribute: string) {
340         if (container && suggestedAttribute && container.includes(suggestedAttribute)) {
341             const index: number = container.indexOf(suggestedAttribute);
342             console.log(index);
343             if (index !== -1) {
344                 container.splice(index, 1);
345             }
346         }
347     }
348
349     addAttribute(container: string[], suggestedAttribute: string) {
350         if (container && suggestedAttribute && !container.includes(suggestedAttribute)) {
351             container.push(suggestedAttribute);
352         }
353     }
354
355
356     submitTempAttributes() {
357         this.writeSelectedAttribute(this.functionAndAttributesInput, 'inputs');
358         this.writeSelectedAttribute(this.functionAndAttributesOutput, 'outputs');
359     }
360
361     private writeSelectedAttribute(map: Map<string, string[]>, attributeType: string) {
362         map.forEach((value, key) => {
363             const nodeTemplate = this.getNodeTemplate(key);
364             this.functions.serverFunctions
365                 /* tslint:disable:no-string-literal */
366                 .filter(currentFunction => currentFunction.modelName.includes(nodeTemplate['type']))
367                 .forEach(currentFunction => {
368
369                     if (currentFunction['definition'] && currentFunction['definition']['interfaces']
370                         [Object.keys(currentFunction['definition'] && currentFunction['definition']['interfaces'])]
371                         ['operations']['process'][attributeType]) {
372                         let newAttributes = '';
373                         const attributes = currentFunction['definition'] && currentFunction['definition']['interfaces']
374                             [Object.keys(currentFunction['definition'] && currentFunction['definition']['interfaces'])]
375                             ['operations']['process'][attributeType];
376                         value.forEach(attribute => {
377                             newAttributes += '"' + attribute + '": ' + this.convertToString(attributes[attribute]) + ',';
378                         });
379                         if (value.length > 0) {
380                             this.writeAttribute(newAttributes, attributeType);
381                         }
382                     }
383                 });
384         });
385     }
386
387     private writeAttribute(newAttributes: string, attributeType: string) {
388         newAttributes = this.removeTheLastComma(newAttributes);
389         console.log(newAttributes);
390         let originalAttributes = this.convertToString(this.designerState.template.workflows[this.actionName]
391             [attributeType]);
392         this.createAttributeTypeIfNotExisted(originalAttributes, attributeType);
393         originalAttributes = this.convertToString(this.designerState.template.workflows[this.actionName]
394             [attributeType]);
395         if (originalAttributes.length > 2) {
396             this.designerState.template.workflows[this.actionName][attributeType] =
397                 this.convertToObject(originalAttributes.substr(0, originalAttributes.length - 1)
398                     + ',' + newAttributes + '}');
399         } else {
400             this.designerState.template.workflows[this.actionName][attributeType] =
401                 this.convertToObject(originalAttributes.substr(0, originalAttributes.length - 1)
402                     + newAttributes + '}');
403         }
404
405     }
406
407     private removeTheLastComma(newInputs: string): string {
408         if (newInputs.endsWith(',')) {
409             newInputs = newInputs.substr(0, newInputs.length - 1);
410         }
411         return newInputs;
412     }
413
414     private convertToString = object => JSON.stringify(object);
415
416     private convertToObject = stringValue => JSON.parse(stringValue);
417
418     private getNodeTemplate = (value: string) => this.designerState.template.node_templates[value];
419
420
421     getAttributesAndOutputs(functionName: string) {
422         this.suggestedAttributes = [];
423         console.log(functionName);
424
425         const nodeTemplate = this.designerState.template.node_templates[functionName];
426         if (nodeTemplate['type'].includes('component-resource-resolution')) {
427             this.isNotComponentResourceResolution = false;
428             this.isParametersHidden = true;
429         } else {
430             this.isNotComponentResourceResolution = true;
431             this.isParametersHidden = true;
432         }
433         /* tslint:disable:no-string-literal */
434         console.log(nodeTemplate['type']);
435         this.functions.serverFunctions
436             /* tslint:disable:no-string-literal */
437             .filter(currentFunction => currentFunction.modelName.includes(nodeTemplate['type']))
438             .forEach(currentFunction => {
439                 if (currentFunction.definition['attributes']) {
440                     Object.keys(currentFunction.definition['attributes']).forEach(attribute => {
441                         this.suggestedAttributes.push(attribute);
442                     });
443                 }
444                 console.log(this.suggestedAttributes);
445
446                 this.selectedFunctionName = functionName;
447
448
449             });
450     }
451
452     addTempOutputAttr(suggestedOutputAndAttribute: string) {
453         console.log('ssss');
454         this.selectedAttributeName = suggestedOutputAndAttribute;
455         this.currentArtifacts = [];
456         const nodeTemplate = this.designerState.template.node_templates[this.selectedFunctionName];
457         if (nodeTemplate['artifacts']
458         ) {
459             Object.keys(nodeTemplate['artifacts']).forEach(key => {
460                 const mappingName = key.split('-')[0];
461                 if (!this.currentArtifacts.includes(mappingName)) {
462                     this.currentArtifacts.push(mappingName);
463                 }
464             });
465         }
466         console.log('happend');
467
468     }
469
470
471     private appendOutputAttributes(outputActionAttribute: OutputActionAttribute) {
472         const entrySchema: string = this.getEntrySchema(outputActionAttribute);
473         const output = '"' + outputActionAttribute.name + '" : {\n' +
474             '            "required" : ' + outputActionAttribute.required + ',\n' +
475             '            "type" : "' + outputActionAttribute.type + '",\n' +
476             '            "description" : "' + outputActionAttribute.description + '",\n' +
477             '            "value\" :' + '{\n' +
478             '             "get_attribute" : ' + outputActionAttribute.value + '\n' +
479             '            }\n';
480
481         return output + entrySchema;
482
483     }
484
485     addArtifactFile(suggestedArtifact: string) {
486         this.currentSuggestedArtifact = suggestedArtifact;
487         this.isParametersHidden = !this.selectedAttributeName.includes('assignment-map');
488         if (!this.isParametersHidden) {
489             this.suggestedMappingParameters = this.getSuggestedMappingParameters(suggestedArtifact);
490         }
491     }
492
493     private getSuggestedMappingParameters(suggestedArtifact: string) {
494         const suggestedMappingParameters = [];
495
496         this.cbaPackage.mapping.files.forEach(((value, key) => {
497             if (key.includes(suggestedArtifact)) {
498
499                 JSON.parse(value).forEach(value2 => {
500                     suggestedMappingParameters.push(value2['name']);
501                 });
502             }
503         }));
504         return suggestedMappingParameters;
505     }
506
507     addSuggestedMappingParameter(suggestedMappingParameter: string) {
508         this.addAttribute(this.selectedParameterList, suggestedMappingParameter);
509         this.deleteAttribute(this.suggestedMappingParameters, suggestedMappingParameter);
510
511     }
512
513     editAttribute(input: any) {
514         this.suggestedEditedAttribute = input;
515     }
516
517     private createAttributeTypeIfNotExisted(originalAttributes: string, attributeType: string) {
518         if (!originalAttributes) {
519             this.designerState.template.workflows[this.actionName][attributeType] = {};
520         }
521     }
522
523     private checkIfTypeIsList(type: string) {
524         return type.includes('list');
525     }
526
527     markDeletedInput(input: any) {
528         this.suggestedDeletedInput = input;
529     }
530
531     deleteActionAttribute() {
532         delete this.designerState.template.workflows[this.actionName]
533             ['inputs'][this.suggestedDeletedInput.name];
534         this.deleteAttribute(this.inputs, this.suggestedDeletedInput);
535
536         delete this.designerState.template.workflows[this.actionName]
537             ['outputs'][this.suggestedDeletedInput.name];
538         this.deleteAttribute(this.outputs, this.suggestedDeletedInput);
539     }
540 }