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';
15 import { PackageCreationService } from '../../package-creation.service';
19 selector: 'app-templ-mapp-creation',
20 templateUrl: './templ-mapp-creation.component.html',
21 styleUrls: ['./templ-mapp-creation.component.css']
23 export class TemplMappCreationComponent implements OnInit, OnDestroy {
24 @Output() showListView = new EventEmitter<any>();
25 @Output() showCreationView = new EventEmitter<any>();
26 public uploadedFiles: FileSystemFileEntry[] = [];
27 fileNames: Set<string> = new Set();
28 jsonConvert = new JsonConvert();
29 public files: NgxFileDropEntry[] = [];
31 templateInfo = new TemplateInfo();
32 variables: string[] = [];
33 dtOptions: DataTables.Settings = {};
34 initDtOptions: DataTables.Settings = {};
35 // We use this trigger because fetching the list of persons can be quite long,
36 // thus we ensure the data is fetched before rendering
37 dtTrigger = new Subject();
38 resTableDtTrigger = new Subject();
39 resourceDictionaryRes: ResourceDictionary[] = [];
40 allowedExt = ['.vtl'];
41 @ViewChild(DataTableDirective, { static: false })
42 dtElement: DataTableDirective;
43 MappingAdapter: MappingAdapter;
45 templateFileContent: string;
46 templateExt = 'Velcoity';
47 dependancies = new Map<string, Array<string>>();
48 dependanciesSource = new Map<string, string>();
53 fileToDelete: any = {};
56 private packageCreationStore: PackageCreationStore,
57 private templateStore: TemplateStore,
58 private packageCreationUtils: PackageCreationUtils,
59 private toastr: ToastrService,
60 private sharedService: SharedService,
61 private packageCreationService: PackageCreationService,
62 private tourService: TourService,
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.fileToDelete = templateInfo.fileName;
73 this.fileName = templateInfo.fileName.split('/')[1];
75 this.fileName = this.fileName.split('-')[0];
77 if (templateInfo.type === 'mapping' || templateInfo.type.includes('mapping')) {
78 this.mappingRes = templateInfo.mapping;
79 this.currentMapping = Object.assign({}, templateInfo);
80 this.resourceDictionaryRes = [];
81 this.resTableDtTrigger.next();
84 this.currentMapping = Any;
86 this.templateFileContent = templateInfo.fileContent;
87 this.currentTemplate = Object.assign({}, templateInfo);
89 if (templateInfo.type === 'template' || templateInfo.type.includes('template')) {
90 this.currentTemplate.fileName = 'Templates/' + this.fileName + '-template.vtl';
92 this.currentTemplate = Any;
97 this.sharedService.isEdit().subscribe(res => {
98 console.log('------------------------');
103 console.log('remove ----');
104 this.currentMapping = {};
105 this.currentTemplate = {};
107 this.templateFileContent = '';
108 this.resourceDictionaryRes = [];
109 this.mappingRes = [];
113 this.initDtOptions = {
114 pagingType: 'full_numbers',
120 pagingType: 'full_numbers',
128 switch (this.templateExt) {
140 fileExtensionFromString(filename: string): string {
141 const fileExtension = filename.substring(filename.lastIndexOf('.') + 1);
142 return fileExtension;
145 public getTemplateVariable(fileContent: string) {
146 const variables: string[] = [];
147 const stringsSlittedByBraces = fileContent.split('${');
148 const stringsDefaultByDollarSignOnly = fileContent.split('"$');
150 for (let i = 1; i < stringsSlittedByBraces.length; i++) {
151 const element = stringsSlittedByBraces[i];
153 const firstElement = element.split('}')[0];
154 if (!variables.includes(firstElement)) {
155 variables.push(firstElement);
157 console.log(firstElement);
162 for (let i = 1; i < stringsDefaultByDollarSignOnly.length; i++) {
163 const element = stringsDefaultByDollarSignOnly[i];
164 if (element && !element.includes('$')) {
165 const firstElement = element.split('"')[0]
167 .replace('}', '').trim();
168 if (!variables.includes(firstElement)) {
169 variables.push(firstElement);
176 public dropped(files: NgxFileDropEntry[]) {
178 for (const droppedFile of files) {
179 // Is it a file? & Not added before
180 if (droppedFile.fileEntry.isFile) {
181 const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
182 this.uploadedFiles.push(fileEntry);
183 this.fileNames.add(fileEntry.name);
189 this.uploadedFiles.splice(index, 1);
193 // Delete from templates
194 this.sharedService.deleteFromList(this.fileName);
195 this.packageCreationStore.state.templates.files.delete(this.fileToDelete);
196 // Delete from Mapping
197 this.packageCreationStore.state.mapping.files.delete(this.fileToDelete);
199 this.packageCreationStore.state.templates.files.size > 0 ||
200 this.packageCreationStore.state.mapping.files.size > 0
207 this.dependancies.clear();
208 this.dependanciesSource.clear();
209 if (this.allowedExt.includes('.csv') || this.allowedExt.includes('.xml')) {
210 this.fetchkeysfromfile();
212 this.setTemplateFilesToStore();
214 $('.btn-cancel').click();
217 fetchkeysfromfile() {
218 for (const droppedFile of this.uploadedFiles) {
219 droppedFile.file((file: File) => {
220 const fileReader = new FileReader();
221 fileReader.onload = (e) => {
222 const fileExt = this.fileExtensionFromString(droppedFile.name);
223 if (fileExt === 'csv') {
224 this.variables = fileReader.result.toString().split(',');
226 const parser = new XmlParser();
227 this.variables = parser.getVariables(fileReader.result.toString());
229 console.log(this.variables);
230 this.getMappingTableFromTemplate(null);
233 fileReader.readAsText(file);
236 this.uploadedFiles = [];
239 private convertDictionaryToMap(resourceDictionaries: ResourceDictionary[]): Mapping[] {
240 const mapArray: Mapping[] = [];
241 for (const resourceDictionary of resourceDictionaries) {
242 this.MappingAdapter = new MappingAdapter(resourceDictionary, this.dependancies, this.dependanciesSource);
243 mapArray.push(this.MappingAdapter.ToMapping());
245 console.log(mapArray);
249 setTemplateFilesToStore() {
250 for (const droppedFile of this.uploadedFiles) {
251 droppedFile.file((file: File) => {
252 const fileReader = new FileReader();
253 fileReader.onload = (e) => {
254 this.templateFileContent = fileReader.result.toString();
255 this.variables = this.getTemplateVariable(this.templateFileContent);
258 fileReader.readAsText(file);
261 this.uploadedFiles = [];
264 textChanges(code: any, fileName: string) {
265 // this.packageCreationStore.addTemplate(fileName, code);
266 this.templateFileContent = code;
269 public fileOver(event) {
273 public fileLeave(event) {
277 resetTheUploadedFiles() {
278 this.uploadedFiles = [];
282 console.log('open List view');
283 this.showListView.emit('tell parent to open create views');
287 console.log('close creation view');
288 this.showCreationView.emit('close create form and open list');
291 getMappingTableFromTemplate(e) {
292 console.log('-' + this.templateFileContent + '-');
293 this.resourceDictionaryRes = [];
297 if (this.variables && this.variables.length > 0) {
299 this.packageCreationService.getTemplateAndMapping(this.variables).subscribe(res => {
300 let message = 'Attributes are Fetched';
301 this.mappingRes = [];
302 this.resourceDictionaryRes = res;
303 console.log(this.resourceDictionaryRes);
305 if (this.resourceDictionaryRes && this.resourceDictionaryRes.length <= 0) {
306 message = 'No values for those attributes';
308 this.toastr.success(message, 'Success');
310 this.toastr.error('Error');
316 if (!this.dependanciesSource.has(key)) {
317 this.dependanciesSource.set(key, map.key);
323 this.templateFileContent = '';
324 this.resourceDictionaryRes = [];
325 this.mappingRes = [];
326 this.currentMapping = {};
327 this.currentTemplate = {};
328 // this.closeCreationForm();
332 // check file duplication
333 console.log('----------- mode ' + this.edit);
335 (!(this.packageCreationStore.fileExist('Templates/' + this.fileName + '-mapping.json')
336 || this.packageCreationStore.fileExist('Templates/' + this.fileName + '-template' + this.getFileExtension())))
339 // Save Mapping to Store
340 if (this.resourceDictionaryRes && this.resourceDictionaryRes.length > 0) {
341 const mapArray = this.convertDictionaryToMap(this.resourceDictionaryRes);
342 this.packageCreationStore.addMapping('Templates/' + this.fileName + '-mapping.json',
343 this.packageCreationUtils.transformToJson(this.jsonConvert.serialize(mapArray)));
344 this.resourceDictionaryRes = [];
346 // Save Template to store
347 // if (this.templateFileContent) {
348 this.packageCreationStore.addTemplate('Templates/' + this.fileName + '-template' + this.getFileExtension(),
349 this.templateFileContent);
350 this.templateFileContent = '';
353 this.toastr.success('File is created', 'success');
355 if (localStorage.getItem('tour-guide') !== 'end' && localStorage.getItem('tour-guide') !== 'false') {
356 this.tourService.goto('tm-templateEdit');
359 console.log('this file already exist');
360 this.toastr.error('File name already exist', 'Error');
363 this.toastr.error('Add the file name', 'Error');
368 selectSource(dict, e) {
369 const source = e.target.value;
370 let keyDepend = null;
371 this.dependancies.set(dict.name, null);
373 keyDepend = dict.definition.sources[source].properties['key-dependencies'] || null;
378 this.dependancies.set(dict.name, keyDepend);
380 // this.dependancies.delete(dict.name);
381 // this.dependanciesSource.delete(dict.name);
383 this.dependanciesSource.set(dict.name, source);
384 console.log(this.dependancies);
385 console.log(this.dependanciesSource);
388 getKeys(map: Map<string, any>) {
389 return Array.from(map.keys());
393 return this.dependancies.get(key);
397 this.dtTrigger.next();
399 // if (this.dtElement.dtInstance) {
400 // console.log('rerender');
401 // this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
402 // dtInstance.destroy();
403 // this.dtElement.dtOptions = this.dtOptions;
404 // this.dtElement.dtTrigger.next();
405 // dtInstance.draw();
408 // this.dtTrigger.next();
412 ngOnDestroy(): void {
413 // Do not forget to unsubscribe the event
414 this.dtTrigger.unsubscribe();
415 this.resTableDtTrigger.unsubscribe();
419 class DependancyVal {
426 this.source = source;
427 this.keyDepend = keyDepend;