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