347f304c8b03e22172ad9a1aa8235a4cfc4e4a63
[ccsdk/cds.git] /
1 import { Component, OnDestroy, OnInit } from '@angular/core';
2 import { DesignerStore } from '../designer.store';
3 import { PackageCreationStore } from '../../package-creation/package-creation.store';
4 import { Subject } from 'rxjs';
5 import { distinctUntilChanged, takeUntil } from 'rxjs/operators';
6 import { CBAPackage } from '../../package-creation/mapping-models/CBAPacakge.model';
7 import { TemplateAndMapping } from '../../package-creation/template-mapping/TemplateAndMapping';
8 import { FunctionsStore } from '../functions.store';
9 import { NodeProcess, NodeTemplate } from '../model/desinger.nodeTemplate.model';
10 import { DesignerDashboardState } from '../model/designer.dashboard.state';
11 import { Action } from '../action-attributes/models/Action';
12
13 @Component({
14     selector: 'app-functions-attribute',
15     templateUrl: './functions-attribute.component.html',
16     styleUrls: ['./functions-attribute.component.css']
17 })
18 export class FunctionsAttributeComponent implements OnInit, OnDestroy {
19
20     ngUnsubscribe = new Subject();
21     designerDashboardState: DecodeSuccessCallback;
22     cbaPackage: CBAPackage;
23     templateAndMappingMap = new Map<string, TemplateAndMapping>();
24     selectedTemplates = new Map<string, TemplateAndMapping>();
25     fileToDelete: string;
26     requiredInputs = new Map<string, {}>();
27     requiredOutputs = new Map<string, {}>();
28     OptionalInputs = new Map<string, {}>();
29     optionalOutputs = new Map<string, {}>();
30     artifactPrefix = false;
31     currentFuncion = new NodeProcess();
32     nodeTemplates = new NodeTemplate('');
33     designerState: DesignerDashboardState;
34     actionName = '';
35     functionName = '';
36     interfaceChildName = '';
37
38
39     constructor(
40         private designerStore: DesignerStore,
41         private packageCreationStore: PackageCreationStore,
42         private functionStore: FunctionsStore
43     ) {
44     }
45
46     ngOnInit() {
47         this.designerStore.state$.subscribe(designerDashboardState => {
48             this.designerState = designerDashboardState;
49             this.actionName = this.designerState.actionName;
50             const action = this.designerState.template.workflows[this.actionName] as Action;
51             this.currentFuncion = new NodeProcess();
52             try {
53                 console.log(action);
54                 if (action) {
55                     // this.designerState.functionName
56                     const child = Object.keys(action.steps)[0];
57                     this.functionName = this.designerState.functionName;
58                     console.log(this.designerState.template.node_templates);
59                     console.log(this.designerState);
60                     console.log(this.designerState.template.node_templates[this.functionName]);
61                     //  this.currentFuncion = this.designerState.template.node_templates[this.functionName];
62                     // reset inouts&outputs
63                     this.requiredInputs = new Map<string, {}>();
64                     this.requiredOutputs = new Map<string, {}>();
65                     this.OptionalInputs = new Map<string, {}>();
66                     this.optionalOutputs = new Map<string, {}>();
67                     this.toNodeProcess(this.designerState.template.node_templates[this.functionName], this.functionName);
68                     const type = this.designerState.template.node_templates[this.functionName].type;
69                     this.getNodeType(type);
70                     this.onInitMapping();
71                 }
72             } catch (e) { }
73         });
74
75         this.packageCreationStore.state$
76             .subscribe(cbaPackage => {
77                 this.cbaPackage = cbaPackage;
78                 console.log('File name =>================== ');
79                 console.log(this.cbaPackage.templates.files);
80                 this.cbaPackage.templates.files.forEach((value, key) => {
81                     console.log('File name => ' + key);
82                     const templateAndMapping = new TemplateAndMapping();
83                     templateAndMapping.isTemplate = true;
84                     const isFromTemplate = true;
85                     this.setIsMappingOrTemplate(key, templateAndMapping, isFromTemplate);
86                 });
87
88                 this.cbaPackage.mapping.files.forEach((value, key) => {
89                     const templateAndMapping = new TemplateAndMapping();
90                     templateAndMapping.isMapping = true;
91                     const isFromTemplate = false;
92                     this.setIsMappingOrTemplate(key, templateAndMapping, isFromTemplate);
93                 });
94             });
95
96     }
97
98     onInitMapping() {
99         // selectedTemplates , templateAndMappingMap
100         this.selectedTemplates = new Map<string, TemplateAndMapping>();
101         try {
102             const functionMap = this.designerState.template.node_templates[this.functionName].artifacts;
103             console.log(this.templateAndMappingMap);
104
105             Object.keys(functionMap).forEach((file) => {
106                 const filename = file.substring(0, file.lastIndexOf('-'));
107                 console.log(filename);
108                 if (this.templateAndMappingMap.has(filename)) {
109                     this.selectedTemplates.set(filename, this.templateAndMappingMap.get(filename));
110                 }
111             });
112
113
114         } catch (e) { }
115     }
116
117     toNodeProcess(nodeTemplate, functionName) {
118         console.log(nodeTemplate);
119         this.currentFuncion['instance-name'] = functionName;
120         // tslint:disable-next-line: no-string-literal
121         this.currentFuncion['type'] = nodeTemplate['type'];
122         if (nodeTemplate.interfaces && Object.keys(nodeTemplate.interfaces).length > 0) {
123             const nodeName = Object.keys(nodeTemplate.interfaces)[0];
124             // console.log(Object.keys(nodeTemplate.interfaces));
125             // tslint:disable-next-line: no-string-literal
126             const inputs = nodeTemplate.interfaces[nodeName]['operations']['process']['inputs'];
127             // tslint:disable-next-line: no-string-literal
128             const outputs = nodeTemplate.interfaces[nodeName]['operations']['process']['outputs'];
129
130             // console.log(inputs);
131
132             if (inputs) {
133                 for (const [key, value] of Object.entries(inputs)) {
134                     console.log(key + ' - ' + value);
135                     this.currentFuncion.inputs[key] = value;
136                 }
137             }
138             if (outputs) {
139                 for (const [key, value] of Object.entries(outputs)) {
140                     console.log(key + '-' + value);
141                     this.currentFuncion.outputs[key] = value;
142                 }
143             }
144         }
145     }
146     ngOnDestroy() {
147         this.ngUnsubscribe.next();
148         this.ngUnsubscribe.complete();
149     }
150
151     addTemplates() { }
152
153     saveFunctionData() {
154         this.nodeTemplates = new NodeTemplate('');
155         // tslint:disable-next-line: variable-name
156         const node_templates = {};
157         const finalFunctionData = this.currentFuncion;
158         // tslint:disable-next-line: no-string-literal
159         const type = finalFunctionData['type'];
160         const instanceName = finalFunctionData['instance-name'];
161         // insert selected templates in nodeTemplates.artifacts
162         this.selectedTemplates.forEach((value, key) => {
163             console.log(key);
164             console.log(value);
165             console.log(finalFunctionData.inputs['artifact-prefix-names']);
166
167             if (finalFunctionData.inputs['artifact-prefix-names'] === undefined) {
168                 finalFunctionData.inputs['artifact-prefix-names'] = [key];
169             } else if (
170                 Array.isArray(finalFunctionData.inputs['artifact-prefix-names']) &&
171                 !finalFunctionData.inputs['artifact-prefix-names'].includes(key)
172             ) {
173                 finalFunctionData.inputs['artifact-prefix-names'].push(key);
174             }
175
176             if (value.isMapping) {
177                 this.nodeTemplates.artifacts[key + '-mapping'] = {
178                     type: 'artifact-mapping-resource',
179                     file: 'Templates/' + key + '-mapping.json'
180                 };
181             }
182
183             if (value.isTemplate) {
184                 this.nodeTemplates.artifacts[key + '-template'] = {
185                     type: 'artifact-template-resource',
186                     file: 'Templates/' + key + '-template.vtl'
187                 };
188             }
189         });
190         // instantiate the final node_template object to save
191
192         this.nodeTemplates.type = type;
193         node_templates[finalFunctionData['instance-name']] = this.nodeTemplates;
194
195         delete finalFunctionData['instance-name'];
196         // tslint:disable-next-line: no-string-literal
197         delete finalFunctionData['type'];
198
199         this.nodeTemplates.interfaces = {
200             [this.interfaceChildName]: {
201                 operations: {
202                     process: {
203                         ...finalFunctionData,
204                     }
205                 }
206             }
207         };
208
209         console.log(finalFunctionData);
210         console.log(node_templates);
211         // tslint:disable-next-line: no-unused-expression
212         this.designerStore.addNodeTemplate(instanceName, type, node_templates[instanceName]);
213     }
214     // Template logic
215     private setIsMappingOrTemplate(key: string, templateAndMapping: TemplateAndMapping, isFromTemplate: boolean) {
216         const nameOfFile = isFromTemplate ?
217             key.split('/')[1].split('.')[0].split('-template')[0]
218             : key.split('/')[1].split('.')[0].split('-mapping')[0];
219         // const fullName = nameOfFile + ',' + key.split('.');
220         if (this.templateAndMappingMap.has(nameOfFile)) {
221             const templateAndMappingExisted = this.templateAndMappingMap.get(nameOfFile);
222             !isFromTemplate ? templateAndMappingExisted.isMapping = true : templateAndMappingExisted.isTemplate = true;
223             this.templateAndMappingMap.set(nameOfFile, templateAndMappingExisted);
224         } else {
225             this.templateAndMappingMap.set(nameOfFile, templateAndMapping);
226         }
227
228     }
229
230     setArtifact(predefined: boolean) {
231         if (predefined) {
232             this.currentFuncion.inputs['artifact-prefix-names'] = [];
233         } else {
234             this.currentFuncion.inputs['artifact-prefix-names'] = { get_input: 'template-prefix' };
235         }
236     }
237     addToInputs(optionalInput) {
238         this.requiredInputs.set(optionalInput, this.OptionalInputs.get(optionalInput));
239         this.OptionalInputs.delete(optionalInput);
240     }
241
242     setTemplate(file: string) {
243         if (this.selectedTemplates.has(file)) {
244             this.selectedTemplates.delete(file);
245         } else {
246             this.selectedTemplates.set(file, this.templateAndMappingMap.get(file));
247         }
248         console.log(this.selectedTemplates);
249     }
250
251     getKeys(map: Map<string, any>) {
252         return Array.from(map.keys());
253     }
254     getValue(file: string, map: Map<string, any>) {
255         return map.get(file);
256     }
257
258     getObjectKey(object) {
259         // console.log(object);
260         return Object.keys(object);
261     }
262     getObjectValue(object) {
263         return Object.values(object);
264     }
265     getNodeType(nodeName: string) {
266         this.functionStore.state$
267             .subscribe(state => {
268                 console.log(state);
269                 console.log(nodeName);
270                 const functions = state.serverFunctions;
271                 // tslint:disable-next-line: prefer-for-of
272                 for (let i = 0; i < functions.length; i++) {
273                     if (functions[i].modelName === nodeName) {
274                         // tslint:disable: no-string-literal
275                         console.log(functions[i].definition['interfaces']);
276                         this.getInputFields(functions[i].definition['interfaces'], 'outputs');
277                         this.getInputFields(functions[i].definition['interfaces'], 'inputs');
278                         break;
279                     }
280                 }
281             });
282     }
283
284     getInputFields(interfaces, type) {
285
286         if (type === 'inputs') {
287             this.requiredInputs = new Map<string, {}>();
288             this.OptionalInputs = new Map<string, {}>();
289         } else {
290             this.requiredOutputs = new Map<string, {}>();
291             this.optionalOutputs = new Map<string, {}>();
292
293         }
294         const nodeName = Object.keys(interfaces)[0];
295         this.interfaceChildName = nodeName;
296         console.log(nodeName + ' ------ ' + type);
297         console.log(interfaces[nodeName]['operations']['process'][type]);
298         const fields = interfaces[nodeName]['operations']['process'][type];
299         this.artifactPrefix = false;
300         for (const [key, value] of Object.entries(fields)) {
301             if (key === 'artifact-prefix-names') {
302                 this.artifactPrefix = true;
303                 // in edit&view mode need to check first if this input||output already exists
304             } else if (key in this.currentFuncion.inputs) {
305                 this.requiredInputs.set(key, Object.assign({}, value));
306             } else if (key in this.currentFuncion.outputs) {
307                 this.requiredOutputs.set(key, Object.assign({}, value));
308             } else if (value['required']) {
309                 console.log('This field is required = ' + key);
310                 if (type === 'inputs') {
311                     this.requiredInputs.set(key, Object.assign({}, value));
312                 } else {
313                     this.requiredOutputs.set(key, Object.assign({}, value));
314                 }
315             } else {
316                 console.log('This field is Optional ' + key);
317                 if (type === 'inputs') {
318                     this.OptionalInputs.set(key, Object.assign({}, value));
319                 } else {
320                     this.optionalOutputs.set(key, Object.assign({}, value));
321                 }
322             }
323         }
324
325         // console.log(this.requiredOutputs);
326     }
327
328
329 }