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/XmlParser';
14 import { TourService } from 'ngx-tour-md-menu';
18 selector: 'app-templ-mapp-creation',
19 templateUrl: './templ-mapp-creation.component.html',
20 styleUrls: ['./templ-mapp-creation.component.css']
22 export class TemplMappCreationComponent implements OnInit, OnDestroy {
23 @Output() showListView = new EventEmitter<any>();
24 @Output() showCreationView = new EventEmitter<any>();
25 public uploadedFiles: FileSystemFileEntry[] = [];
26 fileNames: Set<string> = new Set();
27 jsonConvert = new JsonConvert();
28 public files: NgxFileDropEntry[] = [];
30 templateInfo = new TemplateInfo();
31 variables: string[] = [];
32 dtOptions: DataTables.Settings = {};
33 initDtOptions: DataTables.Settings = {};
34 // We use this trigger because fetching the list of persons can be quite long,
35 // thus we ensure the data is fetched before rendering
36 dtTrigger = new Subject();
37 resTableDtTrigger = new Subject();
38 resourceDictionaryRes: ResourceDictionary[] = [];
39 allowedExt = ['.vtl'];
40 @ViewChild(DataTableDirective, { static: false })
41 dtElement: DataTableDirective;
42 MappingAdapter: MappingAdapter;
44 templateFileContent: string;
45 templateExt = 'Velcoity';
46 dependancies = new Map<string, Array<string>>();
47 dependanciesSource = new Map<string, string>();
52 fileToDelete: any = {};
55 private packageCreationStore: PackageCreationStore,
56 private templateStore: TemplateStore,
57 private packageCreationUtils: PackageCreationUtils,
58 private toastr: ToastrService,
59 private sharedService: SharedService,
60 private tourService: TourService,
65 this.templateStore.state$.subscribe(templateInfo => {
66 // init Template&mapping vars
67 console.log('Oninit');
68 console.log(templateInfo);
69 this.templateInfo = templateInfo;
70 this.fileToDelete = templateInfo.fileName;
71 this.fileName = templateInfo.fileName.split('/')[1];
73 this.fileName = this.fileName.split('-')[0];
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();
82 this.currentMapping = Any;
84 this.templateFileContent = templateInfo.fileContent;
85 this.currentTemplate = Object.assign({}, templateInfo);
87 if (templateInfo.type === 'template' || templateInfo.type.includes('template')) {
88 this.currentTemplate.fileName = 'Templates/' + this.fileName + '-template.vtl';
90 this.currentTemplate = Any;
95 this.sharedService.isEdit().subscribe(res => {
96 console.log('------------------------');
101 console.log('remove ----');
102 this.currentMapping = {};
103 this.currentTemplate = {};
105 this.templateFileContent = '';
106 this.resourceDictionaryRes = [];
107 this.mappingRes = [];
111 this.initDtOptions = {
112 pagingType: 'full_numbers',
118 pagingType: 'full_numbers',
126 switch (this.templateExt) {
138 fileExtensionFromString(filename: string): string {
139 const fileExtension = filename.substring(filename.lastIndexOf('.') + 1);
140 return fileExtension;
143 public getTemplateVariable(fileContent: string) {
144 const variables: string[] = [];
145 const stringsSlittedByBraces = fileContent.split('${');
146 const stringsDefaultByDollarSignOnly = fileContent.split('"$');
148 for (let i = 1; i < stringsSlittedByBraces.length; i++) {
149 const element = stringsSlittedByBraces[i];
151 const firstElement = element.split('}')[0];
152 if (!variables.includes(firstElement)) {
153 variables.push(firstElement);
155 console.log(firstElement);
160 for (let i = 1; i < stringsDefaultByDollarSignOnly.length; i++) {
161 const element = stringsDefaultByDollarSignOnly[i];
162 if (element && !element.includes('$')) {
163 const firstElement = element.split('"')[0]
165 .replace('}', '').trim();
166 if (!variables.includes(firstElement)) {
167 variables.push(firstElement);
174 public dropped(files: NgxFileDropEntry[]) {
176 for (const droppedFile of files) {
177 // Is it a file? & Not added before
178 if (droppedFile.fileEntry.isFile) {
179 const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
180 this.uploadedFiles.push(fileEntry);
181 this.fileNames.add(fileEntry.name);
187 this.uploadedFiles.splice(index, 1);
191 // Delete from templates
192 this.sharedService.deleteFromList(this.fileName);
193 this.packageCreationStore.state.templates.files.delete(this.fileToDelete);
194 // Delete from Mapping
195 this.packageCreationStore.state.mapping.files.delete(this.fileToDelete);
197 this.packageCreationStore.state.templates.files.size > 0 ||
198 this.packageCreationStore.state.mapping.files.size > 0
205 this.dependancies.clear();
206 this.dependanciesSource.clear();
207 if (this.allowedExt.includes('.csv') || this.allowedExt.includes('.xml')) {
208 this.fetchkeysfromfile();
210 this.setTemplateFilesToStore();
212 $('.btn-cancel').click();
215 fetchkeysfromfile() {
216 for (const droppedFile of this.uploadedFiles) {
217 droppedFile.file((file: File) => {
218 const fileReader = new FileReader();
219 fileReader.onload = (e) => {
220 const fileExt = this.fileExtensionFromString(droppedFile.name);
221 if (fileExt === 'csv') {
222 this.variables = fileReader.result.toString().split(',');
224 const parser = new XmlParser();
225 this.variables = parser.getVariables(fileReader.result.toString());
227 console.log(this.variables);
228 this.getMappingTableFromTemplate(null);
231 fileReader.readAsText(file);
234 this.uploadedFiles = [];
237 private convertDictionaryToMap(resourceDictionaries: ResourceDictionary[]): Mapping[] {
238 const mapArray: Mapping[] = [];
239 for (const resourceDictionary of resourceDictionaries) {
240 this.MappingAdapter = new MappingAdapter(resourceDictionary, this.dependancies, this.dependanciesSource);
241 mapArray.push(this.MappingAdapter.ToMapping());
243 console.log(mapArray);
247 setTemplateFilesToStore() {
248 for (const droppedFile of this.uploadedFiles) {
249 droppedFile.file((file: File) => {
250 const fileReader = new FileReader();
251 fileReader.onload = (e) => {
252 this.templateFileContent = fileReader.result.toString();
253 this.variables = this.getTemplateVariable(this.templateFileContent);
256 fileReader.readAsText(file);
259 this.uploadedFiles = [];
262 textChanges(code: any, fileName: string) {
263 // this.packageCreationStore.addTemplate(fileName, code);
264 this.templateFileContent = code;
267 public fileOver(event) {
271 public fileLeave(event) {
275 resetTheUploadedFiles() {
276 this.uploadedFiles = [];
280 console.log('open List view');
281 this.showListView.emit('tell parent to open create views');
285 console.log('close creation view');
286 this.showCreationView.emit('close create form and open list');
289 getMappingTableFromTemplate(e) {
290 console.log('-' + this.templateFileContent + '-');
291 this.resourceDictionaryRes = [];
295 if (this.variables && this.variables.length > 0) {
297 this.packageCreationStore.getTemplateAndMapping(this.variables).subscribe(res => {
298 let message = 'Attributes are Fetched';
299 this.mappingRes = [];
300 this.resourceDictionaryRes = res;
301 console.log(this.resourceDictionaryRes);
303 if (this.resourceDictionaryRes && this.resourceDictionaryRes.length <= 0) {
304 message = 'No values for those attributes';
306 this.toastr.success(message, 'Success');
308 this.toastr.error('Error');
314 if (!this.dependanciesSource.has(key)) {
315 this.dependanciesSource.set(key, map.key);
321 this.templateFileContent = '';
322 this.resourceDictionaryRes = [];
323 this.mappingRes = [];
324 this.currentMapping = {};
325 this.currentTemplate = {};
326 // this.closeCreationForm();
330 // check file duplication
331 console.log('----------- mode ' + this.edit);
333 (!(this.packageCreationStore.fileExist('Templates/' + this.fileName + '-mapping.json')
334 || this.packageCreationStore.fileExist('Templates/' + this.fileName + '-template' + this.getFileExtension())))
337 // Save Mapping to Store
338 if (this.resourceDictionaryRes && this.resourceDictionaryRes.length > 0) {
339 const mapArray = this.convertDictionaryToMap(this.resourceDictionaryRes);
340 this.packageCreationStore.addMapping('Templates/' + this.fileName + '-mapping.json',
341 this.packageCreationUtils.transformToJson(this.jsonConvert.serialize(mapArray)));
342 this.resourceDictionaryRes = [];
344 // Save Template to store
345 // if (this.templateFileContent) {
346 this.packageCreationStore.addTemplate('Templates/' + this.fileName + '-template' + this.getFileExtension(),
347 this.templateFileContent);
348 this.templateFileContent = '';
351 this.toastr.success('File is created', 'success');
353 console.log(this.tourService.getStatus());
354 this.tourService.goto('tm-templateEdit');
356 console.log('this file already exist');
357 this.toastr.error('File name already exist', 'Error');
360 this.toastr.error('Add the file name', 'Error');
365 selectSource(dict, e) {
366 const source = e.target.value;
367 let keyDepend = null;
368 this.dependancies.set(dict.name, null);
370 keyDepend = dict.definition.sources[source].properties['key-dependencies'] || null;
375 this.dependancies.set(dict.name, keyDepend);
377 // this.dependancies.delete(dict.name);
378 // this.dependanciesSource.delete(dict.name);
380 this.dependanciesSource.set(dict.name, source);
381 console.log(this.dependancies);
382 console.log(this.dependanciesSource);
385 getKeys(map: Map<string, any>) {
386 return Array.from(map.keys());
390 return this.dependancies.get(key);
394 this.dtTrigger.next();
396 // if (this.dtElement.dtInstance) {
397 // console.log('rerender');
398 // this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
399 // dtInstance.destroy();
400 // this.dtElement.dtOptions = this.dtOptions;
401 // this.dtElement.dtTrigger.next();
402 // dtInstance.draw();
405 // this.dtTrigger.next();
409 ngOnDestroy(): void {
410 // Do not forget to unsubscribe the event
411 this.dtTrigger.unsubscribe();
412 this.resTableDtTrigger.unsubscribe();
416 class DependancyVal {
423 this.source = source;
424 this.keyDepend = keyDepend;