362986d9641ad8d6e387d0f9ce3af89c0aa6a964
[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$
48             .pipe(
49                 distinctUntilChanged((a: any, b: any) => JSON.stringify(a) === JSON.stringify(b)),
50                 takeUntil(this.ngUnsubscribe))
51             .subscribe(designerDashboardState => {
52                 this.designerDashboardState = designerDashboardState;
53                 this.designerState = designerDashboardState;
54                 this.actionName = this.designerState.actionName;
55                 const action = this.designerState.template.workflows[this.actionName] as Action;
56
57                 console.log(action);
58                 if (action) {
59                     const child = Object.keys(action.steps)[0];
60                     this.functionName = action.steps[child].target;
61                     console.log(this.designerState.template.node_templates[this.functionName]);
62                     //  this.currentFuncion = this.designerState.template.node_templates[this.functionName];
63                     // reset inouts&outputs
64                     this.toNodeProcess(this.designerState.template.node_templates[this.functionName], this.functionName);
65                     const type = this.designerState.template.node_templates[this.functionName].type;
66                     this.getNodeType(type);
67                     this.onInitMapping();
68                 }
69             });
70
71         this.packageCreationStore.state$
72             .subscribe(cbaPackage => {
73                 this.cbaPackage = cbaPackage;
74                 console.log('File name =>================== ');
75                 console.log(this.cbaPackage.templates.files);
76                 this.cbaPackage.templates.files.forEach((value, key) => {
77                     console.log('File name => ' + key);
78                     const templateAndMapping = new TemplateAndMapping();
79                     templateAndMapping.isTemplate = true;
80                     const isFromTemplate = true;
81                     this.setIsMappingOrTemplate(key, templateAndMapping, isFromTemplate);
82                 });
83
84                 this.cbaPackage.mapping.files.forEach((value, key) => {
85                     const templateAndMapping = new TemplateAndMapping();
86                     templateAndMapping.isMapping = true;
87                     const isFromTemplate = false;
88                     this.setIsMappingOrTemplate(key, templateAndMapping, isFromTemplate);
89                 });
90             });
91
92     }
93
94     onInitMapping() {
95         // selectedTemplates , templateAndMappingMap
96         this.selectedTemplates = new Map<string, TemplateAndMapping>();
97         try {
98             const functionMap = this.designerState.template.node_templates[this.functionName].artifacts;
99             console.log(this.templateAndMappingMap);
100
101             Object.keys(functionMap).forEach((file) => {
102                 const filename = file.substring(0, file.lastIndexOf('-'));
103                 console.log(filename);
104                 if (this.templateAndMappingMap.has(filename)) {
105                     this.selectedTemplates.set(filename, this.templateAndMappingMap.get(filename));
106                 }
107             });
108
109
110         } catch (e) { }
111     }
112
113     toNodeProcess(nodeTemplate, functionName) {
114         this.requiredInputs = new Map<string, {}>();
115         this.requiredOutputs = new Map<string, {}>();
116         this.OptionalInputs = new Map<string, {}>();
117         this.optionalOutputs = new Map<string, {}>();
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             // tslint:disable-next-line: no-string-literal
125             const inputs = nodeTemplate.interfaces[nodeName]['operations']['process']['inputs'];
126             // tslint:disable-next-line: no-string-literal
127             const outputs = nodeTemplate.interfaces[nodeName]['operations']['process']['outputs'];
128
129             if (inputs) {
130                 for (const [key, value] of Object.entries(inputs)) {
131                     console.log(key + '-' + value);
132                     this.currentFuncion.inputs[key] = value;
133                 }
134             }
135             if (outputs) {
136                 for (const [key, value] of Object.entries(outputs)) {
137                     console.log(key + '-' + value);
138                     this.currentFuncion.outputs[key] = value;
139                 }
140             }
141         }
142     }
143     ngOnDestroy() {
144         this.ngUnsubscribe.next();
145         this.ngUnsubscribe.complete();
146     }
147
148     saveFunctionData() {
149
150         // tslint:disable-next-line: variable-name
151         const node_templates = {};
152         const finalFunctionData = this.currentFuncion;
153         // tslint:disable-next-line: no-string-literal
154         const type = finalFunctionData['type'];
155         const instanceName = finalFunctionData['instance-name'];
156         // insert selected templates in nodeTemplates.artifacts
157         this.selectedTemplates.forEach((value, key) => {
158             console.log(key);
159             console.log(value);
160             console.log(finalFunctionData.inputs['artifact-prefix-names']);
161
162             if (Array.isArray(finalFunctionData.inputs['artifact-prefix-names'])) {
163                 finalFunctionData.inputs['artifact-prefix-names'].push(key);
164             }
165
166             if (value.isMapping) {
167                 this.nodeTemplates.artifacts[key + '-mapping'] = {
168                     type: 'artifact-mapping-resource',
169                     file: 'Templates/' + key + '-mapping.json'
170                 };
171             }
172
173             if (value.isTemplate) {
174                 this.nodeTemplates.artifacts[key + '-template'] = {
175                     type: 'artifact-template-resource',
176                     file: 'Templates/' + key + '-template.vtl'
177                 };
178             }
179         });
180         // instantiate the final node_template object to save
181
182         this.nodeTemplates.type = type;
183         node_templates[finalFunctionData['instance-name']] = this.nodeTemplates;
184
185         delete finalFunctionData['instance-name'];
186         // tslint:disable-next-line: no-string-literal
187         delete finalFunctionData['type'];
188
189         this.nodeTemplates.interfaces = {
190             [this.interfaceChildName]: {
191                 operations: {
192                     process: {
193                         ...finalFunctionData,
194                     }
195                 }
196             }
197         };
198
199         console.log(finalFunctionData);
200         console.log(node_templates);
201         // tslint:disable-next-line: no-unused-expression
202         this.designerStore.addNodeTemplate(instanceName, type, node_templates[instanceName]);
203     }
204     // Template logic
205     private setIsMappingOrTemplate(key: string, templateAndMapping: TemplateAndMapping, isFromTemplate: boolean) {
206         const nameOfFile = isFromTemplate ?
207             key.split('/')[1].split('.')[0].split('-template')[0]
208             : key.split('/')[1].split('.')[0].split('-mapping')[0];
209         // const fullName = nameOfFile + ',' + key.split('.');
210         if (this.templateAndMappingMap.has(nameOfFile)) {
211             const templateAndMappingExisted = this.templateAndMappingMap.get(nameOfFile);
212             !isFromTemplate ? templateAndMappingExisted.isMapping = true : templateAndMappingExisted.isTemplate = true;
213             this.templateAndMappingMap.set(nameOfFile, templateAndMappingExisted);
214         } else {
215             this.templateAndMappingMap.set(nameOfFile, templateAndMapping);
216         }
217
218     }
219
220     addTemplates() { }
221     setArtifact(predefined: boolean) {
222         if (predefined) {
223             this.currentFuncion.inputs['artifact-prefix-names'] = [];
224         } else {
225             this.currentFuncion.inputs['artifact-prefix-names'] = { get_input: 'template-prefix' };
226         }
227     }
228     addToInputs(optionalInput) {
229         this.requiredInputs.set(optionalInput, this.OptionalInputs.get(optionalInput));
230         this.OptionalInputs.delete(optionalInput);
231     }
232
233     setTemplate(file: string) {
234         if (this.selectedTemplates.has(file)) {
235             this.selectedTemplates.delete(file);
236         } else {
237             this.selectedTemplates.set(file, this.templateAndMappingMap.get(file));
238         }
239         console.log(this.selectedTemplates);
240     }
241
242     getKeys(map: Map<string, any>) {
243         return Array.from(map.keys());
244     }
245     getValue(file: string, map: Map<string, any>) {
246         return map.get(file);
247     }
248
249     getObjectKey(object) {
250         // console.log(object);
251         return Object.keys(object);
252     }
253     getObjectValue(object) {
254         return Object.values(object);
255     }
256     getNodeType(nodeName: string) {
257         this.functionStore.state$
258             .subscribe(state => {
259                 console.log(state);
260                 console.log(nodeName);
261                 const functions = state.serverFunctions;
262                 // tslint:disable-next-line: prefer-for-of
263                 for (let i = 0; i < functions.length; i++) {
264                     if (functions[i].modelName === nodeName) {
265                         // tslint:disable: no-string-literal
266                         console.log(functions[i].definition['interfaces']);
267                         this.getInputFields(functions[i].definition['interfaces'], 'outputs');
268                         this.getInputFields(functions[i].definition['interfaces'], 'inputs');
269                         break;
270                     }
271                 }
272             });
273     }
274
275     getInputFields(interfaces, type) {
276
277         if (type === 'inputs') {
278             this.requiredInputs = new Map<string, {}>();
279             this.OptionalInputs = new Map<string, {}>();
280         } else {
281             this.requiredOutputs = new Map<string, {}>();
282             this.optionalOutputs = new Map<string, {}>();
283
284         }
285         const nodeName = Object.keys(interfaces)[0];
286         this.interfaceChildName = nodeName;
287         console.log(nodeName + ' ------ ' + type);
288         console.log(interfaces[nodeName]['operations']['process'][type]);
289         const fields = interfaces[nodeName]['operations']['process'][type];
290         this.artifactPrefix = false;
291         for (const [key, value] of Object.entries(fields)) {
292             if (key === 'artifact-prefix-names') {
293                 this.artifactPrefix = true;
294             } else if (value['required']) {
295                 console.log('This field is required = ' + key);
296                 if (type === 'inputs') {
297                     this.requiredInputs.set(key, Object.assign({}, value));
298                 } else {
299                     this.requiredOutputs.set(key, Object.assign({}, value));
300                 }
301             } else {
302                 console.log('This field is Optional ' + key);
303                 if (type === 'inputs') {
304                     this.OptionalInputs.set(key, Object.assign({}, value));
305                 } else {
306                     this.optionalOutputs.set(key, Object.assign({}, value));
307                 }
308             }
309         }
310
311         // console.log(this.requiredOutputs);
312     }
313
314
315 }