334b3f484c246c5496bf4e879efefc51cde79dd1
[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, Any } from 'json2typescript';
11 import { ToastrService } from 'ngx-toastr';
12 import { SharedService } from '../shared-service';
13 declare var $: any;
14
15 @Component({
16     selector: 'app-templ-mapp-creation',
17     templateUrl: './templ-mapp-creation.component.html',
18     styleUrls: ['./templ-mapp-creation.component.css']
19 })
20 export class TemplMappCreationComponent implements OnInit, OnDestroy {
21     @Output() showListViewParent = new EventEmitter<any>();
22     @Output() openList = new EventEmitter<any>();
23     public uploadedFiles: FileSystemFileEntry[] = [];
24     private fileNames: Set<string> = new Set();
25     private jsonConvert = new JsonConvert();
26     public files: NgxFileDropEntry[] = [];
27     fileName: any;
28     templateInfo = new TemplateInfo();
29     variables: string[] = [];
30     dtOptions: DataTables.Settings = {};
31     initDtOptions: DataTables.Settings = {};
32     // We use this trigger because fetching the list of persons can be quite long,
33     // thus we ensure the data is fetched before rendering
34     dtTrigger = new Subject();
35     resTableDtTrigger = new Subject();
36     resourceDictionaryRes: ResourceDictionary[] = [];
37     allowedExt = ['.vtl'];
38     @ViewChild(DataTableDirective, { static: false })
39     dtElement: DataTableDirective;
40     MappingAdapter: MappingAdapter;
41     mapping = new Map();
42     templateFileContent: string;
43     templateExt = 'Velcoity';
44     dependancies = new Map<string, Array<string>>();
45     dependanciesSource = new Map<string, string>();
46     mappingRes = [];
47     currentTemplate: any;
48     currentMapping: any;
49     edit = false;
50
51     constructor(
52         private packageCreationStore: PackageCreationStore,
53         private templateStore: TemplateStore,
54         private packageCreationUtils: PackageCreationUtils,
55         private toastr: ToastrService,
56         private sharedService: SharedService
57     ) {
58     }
59
60     ngOnInit() {
61         this.templateStore.state$.subscribe(templateInfo => {
62             // init Template&mapping vars
63             console.log('Oninit');
64             console.log(templateInfo);
65             this.templateInfo = templateInfo;
66             this.fileName = templateInfo.fileName.split('/')[1];
67             if (this.fileName) {
68                 this.fileName = this.fileName.split('-')[0];
69             }
70             if (templateInfo.type === 'mapping' || templateInfo.type.includes('mapping')) {
71                 this.mappingRes = templateInfo.mapping;
72                 this.currentMapping = Object.assign({}, templateInfo);
73                 this.resourceDictionaryRes = [];
74                 this.resTableDtTrigger.next();
75             } else {
76                 this.mappingRes = [];
77                 this.currentMapping = Any;
78             }
79             this.templateFileContent = templateInfo.fileContent;
80             this.currentTemplate = Object.assign({}, templateInfo);
81
82             if (templateInfo.type === 'template' || templateInfo.type.includes('template')) {
83                 this.currentTemplate.fileName = 'Templates/' + this.fileName + '-template.vtl';
84             } else {
85                 this.currentTemplate = Any;
86             }
87
88         });
89
90         this.sharedService.isEdit().subscribe(res => {
91             console.log('------------------------');
92             console.log(res);
93             this.edit = res;
94
95             if (!this.edit) {
96                 console.log('remove ----');
97                 this.currentMapping = {};
98                 this.currentTemplate = {};
99                 this.fileName = '';
100                 this.templateFileContent = '';
101                 this.resourceDictionaryRes = [];
102                 this.mappingRes = [];
103             }
104         });
105
106         this.initDtOptions = {
107             pagingType: 'full_numbers',
108             pageLength: 25,
109             destroy: true,
110             retrieve: true,
111         };
112         this.dtOptions = {
113             pagingType: 'full_numbers',
114             pageLength: 25,
115             destroy: true,
116             retrieve: true,
117         };
118     }
119
120     getFileExtension() {
121         switch (this.templateExt) {
122             case 'Velcoity':
123                 return '.vtl';
124             case 'Koltin':
125                 return '.ktl';
126             case 'Jinja':
127                 return '.j2';
128             default:
129                 return '.vtl';
130         }
131     }
132
133     public getTemplateVariable(fileContent: string) {
134         const variables: string[] = [];
135         const stringsSlittedByBraces = fileContent.split('${');
136         const stringsDefaultByDollarSignOnly = fileContent.split('"$');
137
138         for (let i = 1; i < stringsSlittedByBraces.length; i++) {
139             const element = stringsSlittedByBraces[i];
140             if (element) {
141                 const firstElement = element.split('}')[0];
142                 if (!variables.includes(firstElement)) {
143                     variables.push(firstElement);
144                 } else {
145                     console.log(firstElement);
146                 }
147             }
148         }
149
150         for (let i = 1; i < stringsDefaultByDollarSignOnly.length; i++) {
151             const element = stringsDefaultByDollarSignOnly[i];
152             if (element && !element.includes('$')) {
153                 const firstElement = element.split('"')[0]
154                     .replace('{', '')
155                     .replace('}', '').trim();
156                 if (!variables.includes(firstElement)) {
157                     variables.push(firstElement);
158                 }
159             }
160         }
161         return variables;
162     }
163
164     public dropped(files: NgxFileDropEntry[]) {
165         this.files = files;
166         for (const droppedFile of files) {
167             // Is it a file? & Not added before
168             if (droppedFile.fileEntry.isFile) {
169                 const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
170                 this.uploadedFiles.push(fileEntry);
171                 this.fileNames.add(fileEntry.name);
172
173             }
174         }
175     }
176     removeFile(index) {
177         this.uploadedFiles.splice(index, 1);
178     }
179
180     uploadFile() {
181         this.dependancies.clear();
182         this.dependanciesSource.clear();
183         if (this.allowedExt.includes('.csv')) {
184             this.fetchCSVkeys();
185         } else {
186             this.setTemplateFilesToStore();
187         }
188         $('.btn-cancel').click();
189
190
191     }
192
193     fetchCSVkeys() {
194         for (const droppedFile of this.uploadedFiles) {
195             droppedFile.file((file: File) => {
196                 const fileReader = new FileReader();
197                 fileReader.onload = (e) => {
198                     this.variables = fileReader.result.toString().split(',');
199                     console.log(this.variables);
200                     this.getMappingTableFromTemplate(null);
201
202                 };
203                 fileReader.readAsText(file);
204             });
205         }
206         this.uploadedFiles = [];
207     }
208
209     private convertDictionaryToMap(resourceDictionaries: ResourceDictionary[]): Mapping[] {
210         const mapArray: Mapping[] = [];
211         for (const resourceDictionary of resourceDictionaries) {
212             this.MappingAdapter = new MappingAdapter(resourceDictionary, this.dependancies, this.dependanciesSource);
213             mapArray.push(this.MappingAdapter.ToMapping());
214         }
215         console.log(mapArray);
216         return mapArray;
217     }
218
219     setTemplateFilesToStore() {
220         for (const droppedFile of this.uploadedFiles) {
221             droppedFile.file((file: File) => {
222                 const fileReader = new FileReader();
223                 fileReader.onload = (e) => {
224                     this.templateFileContent = fileReader.result.toString();
225                     this.variables = this.getTemplateVariable(this.templateFileContent);
226
227                 };
228                 fileReader.readAsText(file);
229             });
230         }
231         this.uploadedFiles = [];
232     }
233
234     textChanges(code: any, fileName: string) {
235         //  this.packageCreationStore.addTemplate(fileName, code);
236         this.templateFileContent = code;
237     }
238
239     public fileOver(event) {
240         console.log(event);
241     }
242
243     public fileLeave(event) {
244         console.log(event);
245     }
246     //
247     resetTheUploadedFiles() {
248         this.uploadedFiles = [];
249     }
250
251     openListView() {
252         this.showListViewParent.emit('tell parent to open create views');
253     }
254
255     closeCreationForm() {
256         this.openList.emit('close create form and open list');
257     }
258
259     getMappingTableFromTemplate(e) {
260         console.log('-' + this.templateFileContent + '-');
261         this.resourceDictionaryRes = [];
262         if (e) {
263             e.preventDefault();
264         }
265         if (this.variables && this.variables.length > 0) {
266             console.log('base');
267             this.packageCreationStore.getTemplateAndMapping(this.variables).subscribe(res => {
268                 let message = 'Attributes are Fetched';
269                 this.mappingRes = [];
270                 this.resourceDictionaryRes = res;
271                 console.log(this.resourceDictionaryRes);
272                 this.rerender();
273                 if (this.resourceDictionaryRes && this.resourceDictionaryRes.length <= 0) {
274                     message = 'No values for those attributes';
275                 }
276                 this.toastr.success(message, 'Success');
277             }, err => {
278                 this.toastr.error('Error');
279             });
280         }
281     }
282
283     initMap(key, map) {
284         if (!this.dependanciesSource.has(key)) {
285             this.dependanciesSource.set(key, map.key);
286         }
287         return map.key;
288     }
289     cancel() {
290         this.fileName = '';
291         this.templateFileContent = '';
292         this.resourceDictionaryRes = [];
293         this.mappingRes = [];
294         this.currentMapping = {};
295         this.currentTemplate = {};
296         //   this.closeCreationForm();
297     }
298     saveToStore() {
299         if (this.fileName) {
300             // check file duplication
301             console.log('----------- mode ' + this.edit);
302             if (
303                 (!(this.packageCreationStore.fileExist('Templates/' + this.fileName + '-mapping.json')
304                     || this.packageCreationStore.fileExist('Templates/' + this.fileName + '-template' + this.getFileExtension())))
305                 || this.edit
306             ) {
307                 // Save Mapping to Store
308                 if (this.resourceDictionaryRes && this.resourceDictionaryRes.length > 0) {
309                     const mapArray = this.convertDictionaryToMap(this.resourceDictionaryRes);
310                     this.packageCreationStore.addMapping('Templates/' + this.fileName + '-mapping.json',
311                         this.packageCreationUtils.transformToJson(this.jsonConvert.serialize(mapArray)));
312                     this.resourceDictionaryRes = [];
313                 }
314                 // Save Template to store
315                 // if (this.templateFileContent) {
316                 this.packageCreationStore.addTemplate('Templates/' + this.fileName + '-template' + this.getFileExtension(),
317                     this.templateFileContent);
318                 this.templateFileContent = '';
319                 //  }
320                 this.fileName = '';
321                 this.toastr.success('File is created', 'success');
322                 this.closeCreationForm();
323             } else {
324                 console.log('this file already exist');
325                 this.toastr.error('File name already exist', 'Error');
326             }
327         } else {
328             this.toastr.error('Add the file name', 'Error');
329         }
330     }
331
332
333     selectSource(dict, e) {
334         const source = e.target.value;
335         let keyDepend = null;
336         try {
337             keyDepend = dict.definition.sources[source].properties['key-dependencies'] || null;
338         } catch (e) { }
339         console.log(dict);
340         console.log(source);
341         if (keyDepend) {
342             this.dependancies.set(dict.name, keyDepend);
343         } else {
344             // this.dependancies.delete(dict.name);
345             // this.dependanciesSource.delete(dict.name);
346         }
347         this.dependanciesSource.set(dict.name, source);
348         console.log(this.dependancies);
349         console.log(this.dependanciesSource);
350     }
351
352     getKeys(map: Map<string, any>) {
353         return Array.from(map.keys());
354     }
355
356     getValue(key) {
357         return this.dependancies.get(key);
358     }
359
360     rerender(): void {
361         this.dtTrigger.next();
362
363         // if (this.dtElement.dtInstance) {
364         //     console.log('rerender');
365         //     this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
366         //         dtInstance.destroy();
367         //         this.dtElement.dtOptions = this.dtOptions;
368         //         this.dtElement.dtTrigger.next();
369         //         dtInstance.draw();
370         //     });
371         // } else {
372         //     this.dtTrigger.next();
373         // }
374     }
375
376     ngOnDestroy(): void {
377         // Do not forget to unsubscribe the event
378         this.dtTrigger.unsubscribe();
379         this.resTableDtTrigger.unsubscribe();
380     }
381 }
382
383 class DependancyVal {
384     source: string;
385     keyDepend: any;
386     constructor(
387         source: string,
388         keyDepend: any
389     ) {
390         this.source = source;
391         this.keyDepend = keyDepend;
392     }
393 }