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';
16 selector: 'app-templ-mapp-creation',
17 templateUrl: './templ-mapp-creation.component.html',
18 styleUrls: ['./templ-mapp-creation.component.css']
20 export class TemplMappCreationComponent implements OnInit, OnDestroy {
21 @Output() showListViewParent = new EventEmitter<any>();
22 @Output() openList = new EventEmitter<any>();
23 public uploadedFiles: FileSystemFileEntry[] = [];
24 private fileNames: Set<string> = new Set();
25 private jsonConvert = new JsonConvert();
26 public files: NgxFileDropEntry[] = [];
28 templateInfo = new TemplateInfo();
29 variables: string[] = [];
30 dtOptions: DataTables.Settings = {};
31 initDtOptions: DataTables.Settings = {};
32 // We use this trigger because fetching the list of persons can be quite long,
33 // thus we ensure the data is fetched before rendering
34 dtTrigger = new Subject();
35 resTableDtTrigger = new Subject();
36 resourceDictionaryRes: ResourceDictionary[] = [];
37 allowedExt = ['.vtl'];
38 @ViewChild(DataTableDirective, { static: false })
39 dtElement: DataTableDirective;
40 MappingAdapter: MappingAdapter;
42 templateFileContent: string;
43 templateExt = 'Velcoity';
44 dependancies = new Map<string, Array<string>>();
45 dependanciesSource = new Map<string, string>();
50 fileToDelete: any = {};
53 private packageCreationStore: PackageCreationStore,
54 private templateStore: TemplateStore,
55 private packageCreationUtils: PackageCreationUtils,
56 private toastr: ToastrService,
57 private sharedService: SharedService
62 this.templateStore.state$.subscribe(templateInfo => {
63 // init Template&mapping vars
64 console.log('Oninit');
65 console.log(templateInfo);
66 this.templateInfo = templateInfo;
67 this.fileToDelete = templateInfo.fileName;
68 this.fileName = templateInfo.fileName.split('/')[1];
70 this.fileName = this.fileName.split('-')[0];
72 if (templateInfo.type === 'mapping' || templateInfo.type.includes('mapping')) {
73 this.mappingRes = templateInfo.mapping;
74 this.currentMapping = Object.assign({}, templateInfo);
75 this.resourceDictionaryRes = [];
76 this.resTableDtTrigger.next();
79 this.currentMapping = Any;
81 this.templateFileContent = templateInfo.fileContent;
82 this.currentTemplate = Object.assign({}, templateInfo);
84 if (templateInfo.type === 'template' || templateInfo.type.includes('template')) {
85 this.currentTemplate.fileName = 'Templates/' + this.fileName + '-template.vtl';
87 this.currentTemplate = Any;
92 this.sharedService.isEdit().subscribe(res => {
93 console.log('------------------------');
98 console.log('remove ----');
99 this.currentMapping = {};
100 this.currentTemplate = {};
102 this.templateFileContent = '';
103 this.resourceDictionaryRes = [];
104 this.mappingRes = [];
108 this.initDtOptions = {
109 pagingType: 'full_numbers',
115 pagingType: 'full_numbers',
123 switch (this.templateExt) {
135 public getTemplateVariable(fileContent: string) {
136 const variables: string[] = [];
137 const stringsSlittedByBraces = fileContent.split('${');
138 const stringsDefaultByDollarSignOnly = fileContent.split('"$');
140 for (let i = 1; i < stringsSlittedByBraces.length; i++) {
141 const element = stringsSlittedByBraces[i];
143 const firstElement = element.split('}')[0];
144 if (!variables.includes(firstElement)) {
145 variables.push(firstElement);
147 console.log(firstElement);
152 for (let i = 1; i < stringsDefaultByDollarSignOnly.length; i++) {
153 const element = stringsDefaultByDollarSignOnly[i];
154 if (element && !element.includes('$')) {
155 const firstElement = element.split('"')[0]
157 .replace('}', '').trim();
158 if (!variables.includes(firstElement)) {
159 variables.push(firstElement);
166 public dropped(files: NgxFileDropEntry[]) {
168 for (const droppedFile of files) {
169 // Is it a file? & Not added before
170 if (droppedFile.fileEntry.isFile) {
171 const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
172 this.uploadedFiles.push(fileEntry);
173 this.fileNames.add(fileEntry.name);
179 this.uploadedFiles.splice(index, 1);
185 // Delete from templates
186 this.sharedService.deleteFromList(this.fileName);
187 this.packageCreationStore.state.templates.files.delete(this.fileToDelete);
188 // Delete from Mapping
189 this.packageCreationStore.state.mapping.files.delete(this.fileToDelete);
191 this.packageCreationStore.state.templates.files.size > 0 ||
192 this.packageCreationStore.state.mapping.files.size > 0
194 this.closeCreationForm();
199 this.dependancies.clear();
200 this.dependanciesSource.clear();
201 if (this.allowedExt.includes('.csv')) {
204 this.setTemplateFilesToStore();
206 $('.btn-cancel').click();
212 for (const droppedFile of this.uploadedFiles) {
213 droppedFile.file((file: File) => {
214 const fileReader = new FileReader();
215 fileReader.onload = (e) => {
216 this.variables = fileReader.result.toString().split(',');
217 console.log(this.variables);
218 this.getMappingTableFromTemplate(null);
221 fileReader.readAsText(file);
224 this.uploadedFiles = [];
227 private convertDictionaryToMap(resourceDictionaries: ResourceDictionary[]): Mapping[] {
228 const mapArray: Mapping[] = [];
229 for (const resourceDictionary of resourceDictionaries) {
230 this.MappingAdapter = new MappingAdapter(resourceDictionary, this.dependancies, this.dependanciesSource);
231 mapArray.push(this.MappingAdapter.ToMapping());
233 console.log(mapArray);
237 setTemplateFilesToStore() {
238 for (const droppedFile of this.uploadedFiles) {
239 droppedFile.file((file: File) => {
240 const fileReader = new FileReader();
241 fileReader.onload = (e) => {
242 this.templateFileContent = fileReader.result.toString();
243 this.variables = this.getTemplateVariable(this.templateFileContent);
246 fileReader.readAsText(file);
249 this.uploadedFiles = [];
252 textChanges(code: any, fileName: string) {
253 // this.packageCreationStore.addTemplate(fileName, code);
254 this.templateFileContent = code;
257 public fileOver(event) {
261 public fileLeave(event) {
265 resetTheUploadedFiles() {
266 this.uploadedFiles = [];
270 this.showListViewParent.emit('tell parent to open create views');
273 closeCreationForm() {
274 this.openList.emit('close create form and open list');
277 getMappingTableFromTemplate(e) {
278 console.log('-' + this.templateFileContent + '-');
279 this.resourceDictionaryRes = [];
283 if (this.variables && this.variables.length > 0) {
285 this.packageCreationStore.getTemplateAndMapping(this.variables).subscribe(res => {
286 let message = 'Attributes are Fetched';
287 this.mappingRes = [];
288 this.resourceDictionaryRes = res;
289 console.log(this.resourceDictionaryRes);
291 if (this.resourceDictionaryRes && this.resourceDictionaryRes.length <= 0) {
292 message = 'No values for those attributes';
294 this.toastr.success(message, 'Success');
296 this.toastr.error('Error');
302 if (!this.dependanciesSource.has(key)) {
303 this.dependanciesSource.set(key, map.key);
309 this.templateFileContent = '';
310 this.resourceDictionaryRes = [];
311 this.mappingRes = [];
312 this.currentMapping = {};
313 this.currentTemplate = {};
314 // this.closeCreationForm();
318 // check file duplication
319 console.log('----------- mode ' + this.edit);
321 (!(this.packageCreationStore.fileExist('Templates/' + this.fileName + '-mapping.json')
322 || this.packageCreationStore.fileExist('Templates/' + this.fileName + '-template' + this.getFileExtension())))
325 // Save Mapping to Store
326 if (this.resourceDictionaryRes && this.resourceDictionaryRes.length > 0) {
327 const mapArray = this.convertDictionaryToMap(this.resourceDictionaryRes);
328 this.packageCreationStore.addMapping('Templates/' + this.fileName + '-mapping.json',
329 this.packageCreationUtils.transformToJson(this.jsonConvert.serialize(mapArray)));
330 this.resourceDictionaryRes = [];
332 // Save Template to store
333 // if (this.templateFileContent) {
334 this.packageCreationStore.addTemplate('Templates/' + this.fileName + '-template' + this.getFileExtension(),
335 this.templateFileContent);
336 this.templateFileContent = '';
339 this.toastr.success('File is created', 'success');
340 this.closeCreationForm();
342 console.log('this file already exist');
343 this.toastr.error('File name already exist', 'Error');
346 this.toastr.error('Add the file name', 'Error');
351 selectSource(dict, e) {
352 const source = e.target.value;
353 let keyDepend = null;
355 keyDepend = dict.definition.sources[source].properties['key-dependencies'] || null;
360 this.dependancies.set(dict.name, keyDepend);
362 // this.dependancies.delete(dict.name);
363 // this.dependanciesSource.delete(dict.name);
365 this.dependanciesSource.set(dict.name, source);
366 console.log(this.dependancies);
367 console.log(this.dependanciesSource);
370 getKeys(map: Map<string, any>) {
371 return Array.from(map.keys());
375 return this.dependancies.get(key);
379 this.dtTrigger.next();
381 // if (this.dtElement.dtInstance) {
382 // console.log('rerender');
383 // this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
384 // dtInstance.destroy();
385 // this.dtElement.dtOptions = this.dtOptions;
386 // this.dtElement.dtTrigger.next();
387 // dtInstance.draw();
390 // this.dtTrigger.next();
394 ngOnDestroy(): void {
395 // Do not forget to unsubscribe the event
396 this.dtTrigger.unsubscribe();
397 this.resTableDtTrigger.unsubscribe();
401 class DependancyVal {
408 this.source = source;
409 this.keyDepend = keyDepend;