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 import { XmlParser } from '../utils/ParserFactory/XmlParser';
14 import { TourService } from 'ngx-tour-md-menu';
15 import { PackageCreationService } from '../../package-creation.service';
16 import { ParserFactory } from '../utils/ParserFactory/ParserFactory';
17 import { TemplateType, FileExtension } from '../utils/TemplateType';
21 selector: 'app-templ-mapp-creation',
22 templateUrl: './templ-mapp-creation.component.html',
23 styleUrls: ['./templ-mapp-creation.component.css']
25 export class TemplMappCreationComponent implements OnInit, OnDestroy {
26 @Output() showListView = new EventEmitter<any>();
27 @Output() showCreationView = new EventEmitter<any>();
28 public uploadedFiles: FileSystemFileEntry[] = [];
29 fileNames: Set<string> = new Set();
30 jsonConvert = new JsonConvert();
31 public files: NgxFileDropEntry[] = [];
33 templateInfo = new TemplateInfo();
34 variables: string[] = [];
35 dtOptions: DataTables.Settings = {};
36 initDtOptions: DataTables.Settings = {};
37 // We use this trigger because fetching the list of persons can be quite long,
38 // thus we ensure the data is fetched before rendering
39 dtTrigger = new Subject();
40 resTableDtTrigger = new Subject();
41 resourceDictionaryRes: ResourceDictionary[] = [];
42 allowedExt = ['.vtl'];
43 @ViewChild(DataTableDirective, { static: false })
44 dtElement: DataTableDirective;
45 MappingAdapter: MappingAdapter;
47 templateFileContent: string;
49 dependancies = new Map<string, Array<string>>();
50 dependanciesSource = new Map<string, string>();
55 templatesExist = false;
56 fileToDelete: any = {};
57 parserFactory: ParserFactory;
58 selectedProps: Set<string>;
61 private packageCreationStore: PackageCreationStore,
62 private templateStore: TemplateStore,
63 private packageCreationUtils: PackageCreationUtils,
64 private toastr: ToastrService,
65 private sharedService: SharedService,
66 private packageCreationService: PackageCreationService,
67 private tourService: TourService,
72 this.selectedProps = new Set<string>();
73 this.parserFactory = new ParserFactory();
74 this.templateStore.state$.subscribe(templateInfo => {
75 // init Template&mapping vars
76 console.log('Oninit');
77 console.log(templateInfo);
78 this.templateInfo = templateInfo;
79 this.fileToDelete = templateInfo.fileName;
80 this.fileName = templateInfo.fileName.split('/')[1];
82 this.fileName = this.fileName.split('-')[0];
84 if (templateInfo.type === 'mapping' || templateInfo.type.includes('mapping')) {
85 this.mappingRes = templateInfo.mapping;
86 this.currentMapping = Object.assign({}, templateInfo);
87 this.resourceDictionaryRes = [];
88 this.resTableDtTrigger.next();
91 this.currentMapping = Any;
92 this.resourceDictionaryRes = [];
94 this.templateFileContent = templateInfo.fileContent;
95 this.templateExt = this.templateInfo.ext || this.templateExt;
96 this.currentTemplate = Object.assign({}, templateInfo);
98 if (templateInfo.type === 'template' || templateInfo.type.includes('template')) {
99 console.log('template extension ' + this.templateExt);
100 this.currentTemplate.fileName = 'Templates/' + this.fileName + '-template.' + this.templateExt;
101 console.log(this.currentTemplate.fileName);
103 this.currentTemplate = Any;
109 this.sharedService.isEdit().subscribe(res => {
110 console.log('------------------------....');
111 this.templatesExist = this.packageCreationStore.state.templates.files.size > 0
112 || this.packageCreationStore.state.mapping.files.size > 0;
117 console.log('remove ----');
118 this.currentMapping = {};
119 this.currentTemplate = {};
121 this.templateFileContent = '';
122 this.resourceDictionaryRes = [];
123 this.mappingRes = [];
127 this.initDtOptions = {
128 pagingType: 'full_numbers',
134 targets: [0, 1, 2], // column or columns numbers
135 orderable: false, // set orderable for selected columns
142 pagingType: 'full_numbers',
149 setProp(e, propName, index) {
150 this.resourceDictionaryRes[index][propName] = e.checked;
151 console.log(this.resourceDictionaryRes[index]);
155 if (this.selectedProps.has(value)) {
156 this.selectedProps.delete(value);
158 this.selectedProps.add(value);
163 console.log(this.selectedProps);
164 this.selectedProps.forEach(prop => {
165 this.resourceDictionaryRes.forEach((res, index) => {
166 if (res.name === prop) {
167 console.log('delete...');
168 this.resourceDictionaryRes.splice(index, 1);
169 this.selectedProps.delete(prop);
175 if (this.resourceDictionaryRes.length === this.selectedProps.size) {
176 this.selectedProps = new Set<string>();
178 this.resourceDictionaryRes.forEach(prop => {
180 this.selectedProps.add(prop.name);
186 let currentResDictionary = [];
187 if (this.selectedProps && this.selectedProps.size > 0) {
189 this.packageCreationService.getTemplateAndMapping([...this.selectedProps]).subscribe(res => {
190 let message = 'Re-Auto mapping';
191 this.mappingRes = [];
192 currentResDictionary = res;
193 console.log(currentResDictionary);
194 if (currentResDictionary && currentResDictionary.length <= 0) {
195 message = 'No values for those attributes';
198 // Replcae new values with the old ones
199 currentResDictionary.forEach(curr => {
200 for (let i = 0; i < this.resourceDictionaryRes.length; i++) {
201 if (this.resourceDictionaryRes[i].name === curr.name) {
202 this.resourceDictionaryRes[i] = curr;
207 this.toastr.success(message, 'Success');
209 this.toastr.error('Error');
216 switch (this.templateExt) {
228 fileExtensionFromString(filename: string): string {
229 const fileExtension = filename.substring(filename.lastIndexOf('.') + 1);
230 return fileExtension;
233 public getTemplateVariable(fileContent: string) {
234 // TODO: implement factory Pattern for parser
235 console.log('start parsing........ ' + this.templateExt);
236 const parser = this.parserFactory.getParser(fileContent, this.templateExt);
237 return parser.getVariables(fileContent);
240 public dropped(files: NgxFileDropEntry[]) {
242 for (const droppedFile of files) {
243 // Is it a file? & Not added before
244 if (droppedFile.fileEntry.isFile) {
245 const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
246 this.uploadedFiles.push(fileEntry);
247 this.fileNames.add(fileEntry.name);
253 this.uploadedFiles.splice(index, 1);
257 // Delete from templates
258 this.sharedService.deleteFromList(this.fileName);
259 this.packageCreationStore.state.templates.files.delete(this.fileToDelete);
260 // Delete from Mapping
261 this.packageCreationStore.state.mapping.files.delete(this.fileToDelete);
263 this.packageCreationStore.state.templates.files.size > 0 ||
264 this.packageCreationStore.state.mapping.files.size > 0
271 this.dependancies.clear();
272 this.dependanciesSource.clear();
273 if (this.allowedExt.includes('.csv') || this.allowedExt.includes('.xml')) {
274 this.fetchkeysfromfile();
276 this.setTemplateFilesToStore();
278 $('.btn-cancel').click();
281 fetchkeysfromfile() {
282 for (const droppedFile of this.uploadedFiles) {
283 droppedFile.file((file: File) => {
284 const fileReader = new FileReader();
285 fileReader.onload = (e) => {
286 const fileExt = this.fileExtensionFromString(droppedFile.name);
287 if (fileExt === 'csv') {
288 this.variables = fileReader.result.toString().split(',');
290 const parser = new XmlParser();
291 this.variables = parser.getVariables(fileReader.result.toString());
293 console.log('variables = ' + this.variables);
294 this.getMappingTableFromTemplate(null);
297 fileReader.readAsText(file);
300 this.uploadedFiles = [];
303 private convertDictionaryToMap(resourceDictionaries: ResourceDictionary[]): Mapping[] {
304 const mapArray: Mapping[] = [];
305 for (const resourceDictionary of resourceDictionaries) {
306 this.MappingAdapter = new MappingAdapter(resourceDictionary, this.dependancies, this.dependanciesSource);
307 mapArray.push(this.MappingAdapter.ToMapping());
309 console.log(mapArray);
313 setTemplateFilesToStore() {
314 for (const droppedFile of this.uploadedFiles) {
315 droppedFile.file((file: File) => {
316 const fileReader = new FileReader();
317 fileReader.onload = (e) => {
318 this.templateFileContent = fileReader.result.toString();
319 // this.variables = this.getTemplateVariable(this.templateFileContent);
320 // console.log(this.variables);
323 fileReader.readAsText(file);
326 this.uploadedFiles = [];
329 textChanges(code: any, fileName: string) {
330 // this.packageCreationStore.addTemplate(fileName, code);
331 this.templateFileContent = code;
334 public fileOver(event) {
338 public fileLeave(event) {
342 resetTheUploadedFiles() {
343 this.uploadedFiles = [];
347 console.log('open List view');
348 this.showListView.emit('tell parent to open create views');
352 console.log('close creation view');
353 this.showCreationView.emit('close create form and open list');
356 identify(index, item) {
359 setVelocity(index, value) {
360 // console.log('velocity value = ' + value);
361 // console.log(this.resourceDictionaryRes[index]);
362 // tslint:disable-next-line: no-string-literal
363 this.resourceDictionaryRes[index].definition.property['metadata'] = {
364 'transform-template': value
366 console.log(this.resourceDictionaryRes[index]);
369 getMappingTableFromTemplate(e) {
370 console.log('-' + this.templateFileContent + '-');
371 this.resourceDictionaryRes = [];
375 this.variables = this.getTemplateVariable(this.templateFileContent);
376 console.log('variables = ' + this.variables);
377 if (this.variables && this.variables.length > 0) {
379 this.packageCreationService.getTemplateAndMapping(this.variables).subscribe(res => {
380 let message = 'Attributes are Fetched';
381 this.mappingRes = [];
382 this.resourceDictionaryRes = res;
383 console.log(this.resourceDictionaryRes);
385 if (this.resourceDictionaryRes && this.resourceDictionaryRes.length <= 0) {
386 message = 'No values for those attributes';
388 this.toastr.success(message, 'Success');
390 this.toastr.error('Error');
393 this.toastr.error('Empty or Invalid file format. Validate your file first');
398 if (!this.dependanciesSource.has(key)) {
399 this.dependanciesSource.set(key, map.key);
405 this.templateFileContent = '';
406 this.resourceDictionaryRes = [];
407 this.mappingRes = [];
408 this.currentMapping = {};
409 this.currentTemplate = {};
410 // this.closeCreationForm();
417 // check file duplication
418 console.log('----------- mode ' + this.edit);
420 (!(this.packageCreationStore.fileExist('Templates/' + this.fileName + '-mapping.json')
421 || this.packageCreationStore.fileExist('Templates/' + this.fileName + '-template' + this.getFileExtension())))
424 // Save Mapping to Store
425 if (this.resourceDictionaryRes && this.resourceDictionaryRes.length > 0) {
426 const mapArray = this.convertDictionaryToMap(this.resourceDictionaryRes);
427 this.packageCreationStore.addMapping('Templates/' + this.fileName + '-mapping.json',
428 this.packageCreationUtils.transformToJson(this.jsonConvert.serialize(mapArray)));
429 this.resourceDictionaryRes = [];
431 // Save Template to store
432 // if (this.templateFileContent) {
433 this.packageCreationStore.addTemplate('Templates/' + this.fileName + '-template' + this.getFileExtension(),
434 this.templateFileContent);
435 this.templateFileContent = '';
438 this.toastr.success('File is created', 'success');
440 if (localStorage.getItem('tour-guide') !== 'end' && localStorage.getItem('tour-guide') !== 'false') {
441 this.tourService.goto('tm-templateEdit');
444 console.log('this file already exist');
445 this.toastr.error('File name already exist', 'Error');
448 this.toastr.error('Add the file name', 'Error');
453 selectSource(dict, e) {
454 const source = e.target.value;
455 let keyDepend = null;
456 this.dependancies.set(dict.name, null);
458 keyDepend = dict.definition.sources[source].properties['key-dependencies'] || null;
463 this.dependancies.set(dict.name, keyDepend);
465 // this.dependancies.delete(dict.name);
466 // this.dependanciesSource.delete(dict.name);
468 this.dependanciesSource.set(dict.name, source);
469 console.log(this.dependancies);
470 console.log(this.dependanciesSource);
473 getKeys(map: Map<string, any>) {
474 return Array.from(map.keys());
478 return this.dependancies.get(key);
482 this.dtTrigger.next();
485 ngOnDestroy(): void {
486 // Do not forget to unsubscribe the event
487 this.dtTrigger.unsubscribe();
488 this.resTableDtTrigger.unsubscribe();
489 // this.templateStore.unsubscribe();
493 class DependancyVal {
500 this.source = source;
501 this.keyDepend = keyDepend;