1 import { Component, EventEmitter, OnDestroy, OnInit, Output, ViewChild, AfterViewInit, ElementRef } 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';
14 selector: 'app-templ-mapp-creation',
15 templateUrl: './templ-mapp-creation.component.html',
16 styleUrls: ['./templ-mapp-creation.component.css']
18 export class TemplMappCreationComponent implements OnInit, OnDestroy {
19 @Output() showListViewParent = new EventEmitter<any>();
20 @Output() openList = new EventEmitter<any>();
21 public uploadedFiles: FileSystemFileEntry[] = [];
22 private fileNames: Set<string> = new Set();
23 private jsonConvert = new JsonConvert();
24 public files: NgxFileDropEntry[] = [];
26 templateInfo = new TemplateInfo();
27 variables: string[] = [];
28 dtOptions: DataTables.Settings = {};
29 // We use this trigger because fetching the list of persons can be quite long,
30 // thus we ensure the data is fetched before rendering
31 dtTrigger = new Subject();
32 resTableDtTrigger = new Subject();
33 resourceDictionaryRes: ResourceDictionary[] = [];
34 allowedExt = ['.vtl'];
35 @ViewChild(DataTableDirective, { static: false })
36 dtElement: DataTableDirective;
37 MappingAdapter: MappingAdapter;
39 templateFileContent: string;
40 templateExt = 'Velcoity';
41 dependancies = new Map<string, Array<string>>();
42 dependanciesSource = new Map<string, string>();
48 private packageCreationStore: PackageCreationStore,
49 private templateStore: TemplateStore,
50 private packageCreationUtils: PackageCreationUtils,
51 private toastr: ToastrService
56 this.templateStore.state$.subscribe(templateInfo => {
57 // init Template&mapping vars
58 console.log('----------');
59 console.log(templateInfo);
60 this.templateInfo = templateInfo;
61 this.fileName = templateInfo.fileName.split('/')[1];
63 this.fileName = this.fileName.split('-')[0];
65 if (templateInfo.type === 'mapping' || templateInfo.type.includes('mapping')) {
66 this.mappingRes = templateInfo.mapping;
67 this.currentMapping = Object.assign({}, templateInfo);
68 this.resourceDictionaryRes = [];
69 this.resTableDtTrigger.next();
72 this.currentMapping = Any;
74 this.templateFileContent = templateInfo.fileContent;
75 this.currentTemplate = Object.assign({}, templateInfo);
77 if (templateInfo.type === 'template' || templateInfo.type.includes('template')) {
78 this.currentTemplate.fileName = 'Templates/' + this.fileName + '-template.vtl';
80 this.currentTemplate = Any;
86 pagingType: 'full_numbers',
94 switch (this.templateExt) {
106 public getTemplateVariable(fileContent: string) {
107 const variables: string[] = [];
108 const stringsSlittedByBraces = fileContent.split('${');
109 const stringsDefaultByDollarSignOnly = fileContent.split('"$');
111 for (let i = 1; i < stringsSlittedByBraces.length; i++) {
112 const element = stringsSlittedByBraces[i];
114 const firstElement = element.split('}')[0];
115 if (!variables.includes(firstElement)) {
116 variables.push(firstElement);
118 console.log(firstElement);
123 for (let i = 1; i < stringsDefaultByDollarSignOnly.length; i++) {
124 const element = stringsDefaultByDollarSignOnly[i];
125 if (element && !element.includes('$')) {
126 const firstElement = element.split('"')[0]
128 .replace('}', '').trim();
129 if (!variables.includes(firstElement)) {
130 variables.push(firstElement);
137 public dropped(files: NgxFileDropEntry[]) {
139 for (const droppedFile of files) {
140 // Is it a file? & Not added before
141 if (droppedFile.fileEntry.isFile && !this.fileNames.has(droppedFile.fileEntry.name)) {
142 const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
143 this.uploadedFiles.push(fileEntry);
144 this.fileNames.add(fileEntry.name);
151 this.dependancies.clear();
152 this.dependanciesSource.clear();
153 if (this.allowedExt.includes('.csv')) {
156 this.setTemplateFilesToStore();
161 for (const droppedFile of this.uploadedFiles) {
162 droppedFile.file((file: File) => {
163 const fileReader = new FileReader();
164 fileReader.onload = (e) => {
165 this.variables = fileReader.result.toString().split(',');
166 console.log(this.variables);
167 this.getMappingTableFromTemplate(null);
169 fileReader.readAsText(file);
172 this.uploadedFiles = [];
175 private convertDictionaryToMap(resourceDictionaries: ResourceDictionary[]): Mapping[] {
176 const mapArray: Mapping[] = [];
177 for (const resourceDictionary of resourceDictionaries) {
178 this.MappingAdapter = new MappingAdapter(resourceDictionary, this.dependancies, this.dependanciesSource);
179 mapArray.push(this.MappingAdapter.ToMapping());
181 console.log(mapArray);
185 setTemplateFilesToStore() {
186 for (const droppedFile of this.uploadedFiles) {
187 droppedFile.file((file: File) => {
188 const fileReader = new FileReader();
189 fileReader.onload = (e) => {
190 this.templateFileContent = fileReader.result.toString();
191 this.variables = this.getTemplateVariable(this.templateFileContent);
194 fileReader.readAsText(file);
197 this.uploadedFiles = [];
200 textChanges(code: any, fileName: string) {
201 // this.packageCreationStore.addTemplate(fileName, code);
202 this.templateFileContent = code;
205 public fileOver(event) {
209 public fileLeave(event) {
213 resetTheUploadedFiles() {
214 this.uploadedFiles = [];
218 this.showListViewParent.emit('tell parent to open create views');
221 closeCreationForm() {
222 this.openList.emit('close create form and open list');
225 getMappingTableFromTemplate(e) {
226 console.log('-' + this.templateFileContent + '-');
227 this.resourceDictionaryRes = [];
231 if (this.variables && this.variables.length > 0) {
233 this.packageCreationStore.getTemplateAndMapping(this.variables).subscribe(res => {
234 let message = 'Attributes are Fetched';
235 this.mappingRes = [];
236 this.resourceDictionaryRes = res;
237 console.log(this.resourceDictionaryRes);
239 if (this.resourceDictionaryRes && this.resourceDictionaryRes.length <= 0) {
240 message = 'No values for those attributes';
242 this.toastr.success(message, 'Success');
244 this.toastr.error('Error');
250 if (!this.dependanciesSource.has(key)) {
251 this.dependanciesSource.set(key, map.key);
257 this.templateFileContent = '';
258 this.resourceDictionaryRes = [];
259 this.mappingRes = [];
260 this.currentMapping = {};
261 this.currentTemplate = {};
265 // check file duplication
266 if (!(this.packageCreationStore.fileExist('Templates/' + this.fileName + '-mapping.json')
267 || this.packageCreationStore.fileExist('Templates/' + this.fileName + '-template' + this.getFileExtension()))) {
268 // Save Mapping to Store
269 if (this.resourceDictionaryRes && this.resourceDictionaryRes.length > 0) {
270 const mapArray = this.convertDictionaryToMap(this.resourceDictionaryRes);
271 this.packageCreationStore.addMapping('Templates/' + this.fileName + '-mapping.json',
272 this.packageCreationUtils.transformToJson(this.jsonConvert.serialize(mapArray)));
273 this.resourceDictionaryRes = [];
275 // Save Template to store
276 if (this.templateFileContent) {
277 this.packageCreationStore.addTemplate('Templates/' + this.fileName + '-template' + this.getFileExtension(),
278 this.templateFileContent);
279 this.templateFileContent = '';
282 this.toastr.success('File is created', 'success');
283 this.closeCreationForm();
285 console.log('this file already exist');
286 this.toastr.error('File name already exist', 'Error');
289 this.toastr.error('Add the file name', 'Error');
294 selectSource(dict, e) {
295 const source = e.target.value;
296 let keyDepend = null;
298 keyDepend = dict.definition.sources[source].properties['key-dependencies'] || null;
303 this.dependancies.set(dict.name, keyDepend);
305 // this.dependancies.delete(dict.name);
306 // this.dependanciesSource.delete(dict.name);
308 this.dependanciesSource.set(dict.name, source);
309 console.log(this.dependancies);
310 console.log(this.dependanciesSource);
313 getKeys(map: Map<string, any>) {
314 return Array.from(map.keys());
318 return this.dependancies.get(key);
322 if (this.dtElement.dtInstance) {
323 console.log('rerender');
324 this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
325 dtInstance.destroy();
326 this.dtElement.dtOptions = this.dtOptions;
327 this.dtElement.dtTrigger.next();
331 this.dtTrigger.next();
335 ngOnDestroy(): void {
336 // Do not forget to unsubscribe the event
337 this.dtTrigger.unsubscribe();
341 class DependancyVal {
348 this.source = source;
349 this.keyDepend = keyDepend;