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