628d963cec0539f68ef9812d45b2a1b052a8fa2f
[ccsdk/cds.git] /
1 import { Component, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';
2 import { FileSystemFileEntry, NgxFileDropEntry } from 'ngx-file-drop';
3 import { PackageCreationStore } from '../../package-creation.store';
4 import { TemplateInfo, TemplateStore } from '../../template.store';
5 import { Subject } from 'rxjs';
6 import { ResourceDictionary } from '../../mapping-models/ResourceDictionary.model';
7 import { DataTableDirective } from 'angular-datatables';
8 import { Mapping, MappingAdapter } from '../../mapping-models/mappingAdapter.model';
9 import { PackageCreationUtils } from '../../package-creation.utils';
10 import { JsonConvert } from 'json2typescript';
11
12 @Component({
13     selector: 'app-templ-mapp-creation',
14     templateUrl: './templ-mapp-creation.component.html',
15     styleUrls: ['./templ-mapp-creation.component.css']
16 })
17 export class TemplMappCreationComponent implements OnInit, OnDestroy {
18     @Output() showListViewParent = new EventEmitter<any>();
19
20     public uploadedFiles: FileSystemFileEntry[] = [];
21     private fileNames: Set<string> = new Set();
22     private jsonConvert = new JsonConvert();
23     public files: NgxFileDropEntry[] = [];
24     fileName: any;
25     templateInfo = new TemplateInfo();
26     private variables: string[] = [];
27     dtOptions: DataTables.Settings = {};
28     // We use this trigger because fetching the list of persons can be quite long,
29     // thus we ensure the data is fetched before rendering
30     dtTrigger = new Subject();
31     resTableDtTrigger = new Subject();
32     resourceDictionaryRes: ResourceDictionary[] = [];
33     allowedExt = ['.vtl'];
34     @ViewChild(DataTableDirective, { static: false })
35     dtElement: DataTableDirective;
36     MappingAdapter: MappingAdapter;
37     mapping = new Map();
38     templateFileContent: string;
39     templateExt = 'Velcoity';
40     dependancies = new Map<string, Array<string>>();
41     dependanciesSource = new Map<string, string>();
42     mappingRes = [];
43
44
45
46     constructor(
47         private packageCreationStore: PackageCreationStore,
48         private templateStore: TemplateStore,
49         private packageCreationUtils: PackageCreationUtils
50     ) {
51     }
52
53     ngOnInit() {
54         this.templateStore.state$.subscribe(templateInfo => {
55             console.log('----------');
56             console.log(templateInfo);
57             this.templateInfo = templateInfo;
58             this.fileName = templateInfo.fileName.split('/')[1];
59             if (templateInfo.type === 'mapping') {
60                 this.mappingRes = templateInfo.mapping;
61                 this.resourceDictionaryRes = [];
62                 this.resTableDtTrigger.next();
63             } else {
64
65                 this.templateFileContent = templateInfo.fileContent;
66             }
67         });
68
69         this.dtOptions = {
70             pagingType: 'full_numbers',
71             pageLength: 10,
72             destroy: true,
73             retrieve: true,
74         };
75     }
76
77     getFileExtension() {
78         switch (this.templateExt) {
79             case 'Velcoity':
80                 return '.vtl';
81             case 'Koltin':
82                 return '.ktl';
83             case 'Jinja':
84                 return '.j2';
85             default:
86                 return '.vtl';
87         }
88     }
89
90     public getTemplateVariable(fileContent: string) {
91         const variables: string[] = [];
92         const stringsSlittedByBraces = fileContent.split('${');
93         const stringsDefaultByDollarSignOnly = fileContent.split('"$');
94
95         for (let i = 1; i < stringsSlittedByBraces.length; i++) {
96             const element = stringsSlittedByBraces[i];
97             if (element) {
98                 const firstElement = element.split('}')[0];
99                 if (!variables.includes(firstElement)) {
100                     variables.push(firstElement);
101                 } else {
102                     console.log(firstElement);
103                 }
104             }
105         }
106
107         for (let i = 1; i < stringsDefaultByDollarSignOnly.length; i++) {
108             const element = stringsDefaultByDollarSignOnly[i];
109             if (element && !element.includes('$')) {
110                 const firstElement = element.split('"')[0]
111                     .replace('{', '')
112                     .replace('}', '').trim();
113                 if (!variables.includes(firstElement)) {
114                     variables.push(firstElement);
115                 }
116             }
117         }
118         return variables;
119     }
120
121     public dropped(files: NgxFileDropEntry[]) {
122         this.files = files;
123         for (const droppedFile of files) {
124             // Is it a file? & Not added before
125             if (droppedFile.fileEntry.isFile && !this.fileNames.has(droppedFile.fileEntry.name)) {
126                 const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
127                 this.uploadedFiles.push(fileEntry);
128                 this.fileNames.add(fileEntry.name);
129
130             }
131         }
132     }
133
134     uploadFile() {
135         this.dependancies.clear();
136         this.dependanciesSource.clear();
137         if (this.allowedExt.includes('.csv')) {
138             this.fetchCSVkeys();
139         } else {
140             this.setTemplateFilesToStore();
141         }
142     }
143
144     fetchCSVkeys() {
145         for (const droppedFile of this.uploadedFiles) {
146             droppedFile.file((file: File) => {
147                 const fileReader = new FileReader();
148                 fileReader.onload = (e) => {
149                     this.variables = fileReader.result.toString().split(',');
150                     console.log(this.variables);
151                     this.getMappingTableFromTemplate(null);
152                 };
153                 fileReader.readAsText(file);
154             });
155         }
156         this.uploadedFiles = [];
157     }
158
159     private convertDictionaryToMap(resourceDictionaries: ResourceDictionary[]): Mapping[] {
160         const mapArray: Mapping[] = [];
161         for (const resourceDictionary of resourceDictionaries) {
162             this.MappingAdapter = new MappingAdapter(resourceDictionary, this.dependancies, this.dependanciesSource);
163             mapArray.push(this.MappingAdapter.ToMapping());
164         }
165         console.log(mapArray);
166         return mapArray;
167     }
168
169     setTemplateFilesToStore() {
170         for (const droppedFile of this.uploadedFiles) {
171             droppedFile.file((file: File) => {
172                 const fileReader = new FileReader();
173                 fileReader.onload = (e) => {
174                     this.templateFileContent = fileReader.result.toString();
175                     this.variables = this.getTemplateVariable(this.templateFileContent);
176
177                 };
178                 fileReader.readAsText(file);
179             });
180         }
181         this.uploadedFiles = [];
182     }
183
184     textChanges(code: any, fileName: string) {
185         //  this.packageCreationStore.addTemplate(fileName, code);
186         this.templateFileContent = code;
187     }
188
189     public fileOver(event) {
190         console.log(event);
191     }
192
193     public fileLeave(event) {
194         console.log(event);
195     }
196     //
197     resetTheUploadedFiles() {
198         this.uploadedFiles = [];
199     }
200
201     openListView() {
202         this.showListViewParent.emit('tell parent to open create views');
203     }
204
205     getMappingTableFromTemplate(e) {
206         this.resourceDictionaryRes = [];
207         if (e) {
208             e.preventDefault();
209         }
210         if (this.variables && this.variables.length > 0) {
211             console.log('base');
212             this.packageCreationStore.getTemplateAndMapping(this.variables).subscribe(res => {
213                 this.mappingRes = [];
214                 this.resourceDictionaryRes = res;
215                 console.log(this.resourceDictionaryRes);
216                 this.rerender();
217             });
218         }
219     }
220
221     initMap(key, map) {
222         if (!this.dependanciesSource.has(key)) {
223             this.dependanciesSource.set(key, map.key);
224         }
225         return map.key;
226     }
227     saveToStore() {
228         console.log(this.dependancies);
229         console.log(this.dependanciesSource);
230         if (this.fileName) {
231             // Save Mapping to Store
232             if (this.resourceDictionaryRes && this.resourceDictionaryRes.length > 0) {
233                 const mapArray = this.convertDictionaryToMap(this.resourceDictionaryRes);
234                 this.packageCreationStore.addMapping('Templates/' + this.fileName + '-mapping.json',
235                     this.packageCreationUtils.transformToJson(this.jsonConvert.serialize(mapArray)));
236                 this.resourceDictionaryRes = [];
237             }
238             // Save Template to store
239             if (this.templateFileContent) {
240                 this.packageCreationStore.addTemplate('Templates/' + this.fileName + '-template' + this.getFileExtension(),
241                     this.templateFileContent);
242                 this.templateFileContent = '';
243             }
244         } else {
245
246         }
247     }
248
249     selectSource(dict, e) {
250         const source = e.target.value;
251         let keyDepend = null;
252         try {
253             keyDepend = dict.definition.sources[source].properties['key-dependencies'] || null;
254         } catch (e) { }
255         console.log(dict);
256         console.log(source);
257         if (keyDepend) {
258             this.dependancies.set(dict.name, keyDepend);
259         } else {
260             // this.dependancies.delete(dict.name);
261             // this.dependanciesSource.delete(dict.name);
262         }
263         this.dependanciesSource.set(dict.name, source);
264         console.log(this.dependancies);
265         console.log(this.dependanciesSource);
266     }
267
268     getKeys(map: Map<string, any>) {
269         return Array.from(map.keys());
270     }
271
272     getValue(key) {
273         return this.dependancies.get(key);
274     }
275
276     rerender(): void {
277         if (this.dtElement.dtInstance) {
278             console.log('rerender');
279             this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
280                 dtInstance.destroy();
281                 this.dtElement.dtOptions = this.dtOptions;
282                 this.dtElement.dtTrigger.next();
283                 dtInstance.draw();
284             });
285         } else {
286             this.dtTrigger.next();
287         }
288     }
289
290     ngOnDestroy(): void {
291         // Do not forget to unsubscribe the event
292         this.dtTrigger.unsubscribe();
293     }
294 }
295
296 class DependancyVal {
297     source: string;
298     keyDepend: any;
299     constructor(
300         source: string,
301         keyDepend: any
302     ) {
303         this.source = source;
304         this.keyDepend = keyDepend;
305     }
306 }