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';
17 selector: 'app-templ-mapp-creation',
18 templateUrl: './templ-mapp-creation.component.html',
19 styleUrls: ['./templ-mapp-creation.component.css']
21 export class TemplMappCreationComponent implements OnInit, OnDestroy {
22 @Output() showListView = new EventEmitter<any>();
23 @Output() showCreationView = new EventEmitter<any>();
24 public uploadedFiles: FileSystemFileEntry[] = [];
25 fileNames: Set<string> = new Set();
26 jsonConvert = new JsonConvert();
27 public files: NgxFileDropEntry[] = [];
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;
43 templateFileContent: string;
44 templateExt = 'Velcoity';
45 dependancies = new Map<string, Array<string>>();
46 dependanciesSource = new Map<string, string>();
51 fileToDelete: any = {};
54 private packageCreationStore: PackageCreationStore,
55 private templateStore: TemplateStore,
56 private packageCreationUtils: PackageCreationUtils,
57 private toastr: ToastrService,
58 private sharedService: SharedService
63 this.templateStore.state$.subscribe(templateInfo => {
64 // init Template&mapping vars
65 console.log('Oninit');
66 console.log(templateInfo);
67 this.templateInfo = templateInfo;
68 this.fileToDelete = templateInfo.fileName;
69 this.fileName = templateInfo.fileName.split('/')[1];
71 this.fileName = this.fileName.split('-')[0];
73 if (templateInfo.type === 'mapping' || templateInfo.type.includes('mapping')) {
74 this.mappingRes = templateInfo.mapping;
75 this.currentMapping = Object.assign({}, templateInfo);
76 this.resourceDictionaryRes = [];
77 this.resTableDtTrigger.next();
80 this.currentMapping = Any;
82 this.templateFileContent = templateInfo.fileContent;
83 this.currentTemplate = Object.assign({}, templateInfo);
85 if (templateInfo.type === 'template' || templateInfo.type.includes('template')) {
86 this.currentTemplate.fileName = 'Templates/' + this.fileName + '-template.vtl';
88 this.currentTemplate = Any;
93 this.sharedService.isEdit().subscribe(res => {
94 console.log('------------------------');
99 console.log('remove ----');
100 this.currentMapping = {};
101 this.currentTemplate = {};
103 this.templateFileContent = '';
104 this.resourceDictionaryRes = [];
105 this.mappingRes = [];
109 this.initDtOptions = {
110 pagingType: 'full_numbers',
116 pagingType: 'full_numbers',
124 switch (this.templateExt) {
136 fileExtensionFromString(filename: string): string {
137 const fileExtension = filename.substring(filename.lastIndexOf('.') + 1);
138 return fileExtension;
141 public getTemplateVariable(fileContent: string) {
142 const variables: string[] = [];
143 const stringsSlittedByBraces = fileContent.split('${');
144 const stringsDefaultByDollarSignOnly = fileContent.split('"$');
146 for (let i = 1; i < stringsSlittedByBraces.length; i++) {
147 const element = stringsSlittedByBraces[i];
149 const firstElement = element.split('}')[0];
150 if (!variables.includes(firstElement)) {
151 variables.push(firstElement);
153 console.log(firstElement);
158 for (let i = 1; i < stringsDefaultByDollarSignOnly.length; i++) {
159 const element = stringsDefaultByDollarSignOnly[i];
160 if (element && !element.includes('$')) {
161 const firstElement = element.split('"')[0]
163 .replace('}', '').trim();
164 if (!variables.includes(firstElement)) {
165 variables.push(firstElement);
172 public dropped(files: NgxFileDropEntry[]) {
174 for (const droppedFile of files) {
175 // Is it a file? & Not added before
176 if (droppedFile.fileEntry.isFile) {
177 const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
178 this.uploadedFiles.push(fileEntry);
179 this.fileNames.add(fileEntry.name);
185 this.uploadedFiles.splice(index, 1);
189 // Delete from templates
190 this.sharedService.deleteFromList(this.fileName);
191 this.packageCreationStore.state.templates.files.delete(this.fileToDelete);
192 // Delete from Mapping
193 this.packageCreationStore.state.mapping.files.delete(this.fileToDelete);
195 this.packageCreationStore.state.templates.files.size > 0 ||
196 this.packageCreationStore.state.mapping.files.size > 0
203 this.dependancies.clear();
204 this.dependanciesSource.clear();
205 if (this.allowedExt.includes('.csv') || this.allowedExt.includes('.xml')) {
206 this.fetchkeysfromfile();
208 this.setTemplateFilesToStore();
210 $('.btn-cancel').click();
213 fetchkeysfromfile() {
214 for (const droppedFile of this.uploadedFiles) {
215 droppedFile.file((file: File) => {
216 const fileReader = new FileReader();
217 fileReader.onload = (e) => {
218 const fileExt = this.fileExtensionFromString(droppedFile.name);
219 if (fileExt === 'csv') {
220 this.variables = fileReader.result.toString().split(',');
222 const parser = new XmlParser();
223 this.variables = parser.getVariables(fileReader.result.toString());
225 console.log(this.variables);
226 this.getMappingTableFromTemplate(null);
229 fileReader.readAsText(file);
232 this.uploadedFiles = [];
235 private convertDictionaryToMap(resourceDictionaries: ResourceDictionary[]): Mapping[] {
236 const mapArray: Mapping[] = [];
237 for (const resourceDictionary of resourceDictionaries) {
238 this.MappingAdapter = new MappingAdapter(resourceDictionary, this.dependancies, this.dependanciesSource);
239 mapArray.push(this.MappingAdapter.ToMapping());
241 console.log(mapArray);
245 setTemplateFilesToStore() {
246 for (const droppedFile of this.uploadedFiles) {
247 droppedFile.file((file: File) => {
248 const fileReader = new FileReader();
249 fileReader.onload = (e) => {
250 this.templateFileContent = fileReader.result.toString();
251 this.variables = this.getTemplateVariable(this.templateFileContent);
254 fileReader.readAsText(file);
257 this.uploadedFiles = [];
260 textChanges(code: any, fileName: string) {
261 // this.packageCreationStore.addTemplate(fileName, code);
262 this.templateFileContent = code;
265 public fileOver(event) {
269 public fileLeave(event) {
273 resetTheUploadedFiles() {
274 this.uploadedFiles = [];
278 console.log('open List view');
279 this.showListView.emit('tell parent to open create views');
283 console.log('close creation view');
284 this.showCreationView.emit('close create form and open list');
287 getMappingTableFromTemplate(e) {
288 console.log('-' + this.templateFileContent + '-');
289 this.resourceDictionaryRes = [];
293 if (this.variables && this.variables.length > 0) {
295 this.packageCreationStore.getTemplateAndMapping(this.variables).subscribe(res => {
296 let message = 'Attributes are Fetched';
297 this.mappingRes = [];
298 this.resourceDictionaryRes = res;
299 console.log(this.resourceDictionaryRes);
301 if (this.resourceDictionaryRes && this.resourceDictionaryRes.length <= 0) {
302 message = 'No values for those attributes';
304 this.toastr.success(message, 'Success');
306 this.toastr.error('Error');
312 if (!this.dependanciesSource.has(key)) {
313 this.dependanciesSource.set(key, map.key);
319 this.templateFileContent = '';
320 this.resourceDictionaryRes = [];
321 this.mappingRes = [];
322 this.currentMapping = {};
323 this.currentTemplate = {};
324 // this.closeCreationForm();
328 // check file duplication
329 console.log('----------- mode ' + this.edit);
331 (!(this.packageCreationStore.fileExist('Templates/' + this.fileName + '-mapping.json')
332 || this.packageCreationStore.fileExist('Templates/' + this.fileName + '-template' + this.getFileExtension())))
335 // Save Mapping to Store
336 if (this.resourceDictionaryRes && this.resourceDictionaryRes.length > 0) {
337 const mapArray = this.convertDictionaryToMap(this.resourceDictionaryRes);
338 this.packageCreationStore.addMapping('Templates/' + this.fileName + '-mapping.json',
339 this.packageCreationUtils.transformToJson(this.jsonConvert.serialize(mapArray)));
340 this.resourceDictionaryRes = [];
342 // Save Template to store
343 // if (this.templateFileContent) {
344 this.packageCreationStore.addTemplate('Templates/' + this.fileName + '-template' + this.getFileExtension(),
345 this.templateFileContent);
346 this.templateFileContent = '';
349 this.toastr.success('File is created', 'success');
352 console.log('this file already exist');
353 this.toastr.error('File name already exist', 'Error');
356 this.toastr.error('Add the file name', 'Error');
361 selectSource(dict, e) {
362 const source = e.target.value;
363 let keyDepend = null;
364 this.dependancies.set(dict.name, null);
366 keyDepend = dict.definition.sources[source].properties['key-dependencies'] || null;
371 this.dependancies.set(dict.name, keyDepend);
373 // this.dependancies.delete(dict.name);
374 // this.dependanciesSource.delete(dict.name);
376 this.dependanciesSource.set(dict.name, source);
377 console.log(this.dependancies);
378 console.log(this.dependanciesSource);
381 getKeys(map: Map<string, any>) {
382 return Array.from(map.keys());
386 return this.dependancies.get(key);
390 this.dtTrigger.next();
392 // if (this.dtElement.dtInstance) {
393 // console.log('rerender');
394 // this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
395 // dtInstance.destroy();
396 // this.dtElement.dtOptions = this.dtOptions;
397 // this.dtElement.dtTrigger.next();
398 // dtInstance.draw();
401 // this.dtTrigger.next();
405 ngOnDestroy(): void {
406 // Do not forget to unsubscribe the event
407 this.dtTrigger.unsubscribe();
408 this.resTableDtTrigger.unsubscribe();
412 class DependancyVal {
419 this.source = source;
420 this.keyDepend = keyDepend;