added svcapi ui and camunda code
[it/otf.git] / otf-frontend / client / src / app / layout / modeler / modeler.component.ts
1 /*  Copyright (c) 2019 AT&T Intellectual Property.                             #\r
2 #                                                                              #\r
3 #   Licensed under the Apache License, Version 2.0 (the "License");            #\r
4 #   you may not use this file except in compliance with the License.           #\r
5 #   You may obtain a copy of the License at                                    #\r
6 #                                                                              #\r
7 #       http://www.apache.org/licenses/LICENSE-2.0                             #\r
8 #                                                                              #\r
9 #   Unless required by applicable law or agreed to in writing, software        #\r
10 #   distributed under the License is distributed on an "AS IS" BASIS,          #\r
11 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #\r
12 #   See the License for the specific language governing permissions and        #\r
13 #   limitations under the License.                                             #\r
14 ##############################################################################*/\r
15 \r
16 \r
17 import { Component, OnInit, ViewChild, ElementRef, AfterViewInit, HostListener } from '@angular/core';\r
18 import minimapModule from 'diagram-js-minimap';\r
19 import { FileTransferService } from 'app/shared/services/file-transfer.service';\r
20 import { Buffer } from 'buffer';\r
21 import propertiesPanelModule from 'bpmn-js-properties-panel';\r
22 import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda';\r
23 import * as camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda.json';\r
24 import * as vthTemplate from './templates/elements.json';\r
25 import * as $ from 'jquery';\r
26 import { MatDialog, MatSnackBar } from '@angular/material';\r
27 import { TestHeadService } from 'app/shared/services/test-head.service';\r
28 import { GroupService } from 'app/shared/services/group.service';\r
29 import { TestDefinitionService } from 'app/shared/services/test-definition.service';\r
30 import { CookieService } from 'ngx-cookie-service';\r
31 import { FileService } from 'app/shared/services/file.service';\r
32 import { ActivatedRoute, Router } from '@angular/router';\r
33 import { BpmnFactoryService } from 'app/shared/factories/bpmn-factory.service';\r
34 import { Bpmn } from 'app/shared/models/bpmn.model';\r
35 import { TestDefinitionElement, BpmnInstanceElement } from './test-definition-element.class.js';\r
36 import { FileUploader } from 'ng2-file-upload';\r
37 import { Group } from 'app/shared/models/group.model.js';\r
38 import { AlertSnackbarComponent } from 'app/shared/modules/alert-snackbar/alert-snackbar.component';\r
39 import { AlertModalComponent } from 'app/shared/modules/alert-modal/alert-modal.component';\r
40 \r
41 interface NewVersionOptions {\r
42   versionIndex: number,\r
43   fromFile: Boolean\r
44 }\r
45 \r
46 @Component({\r
47   selector: 'app-modeler',\r
48   templateUrl: './modeler.component.pug',\r
49   styleUrls: [\r
50     './modeler.component.scss',\r
51   ]\r
52 })\r
53 \r
54 export class ModelerComponent implements OnInit {\r
55 \r
56   @ViewChild('container') containerElement: ElementRef;\r
57   @ViewChild('modeler') modelerElement: ElementRef;\r
58   @ViewChild('sidebar') sidebarElement: ElementRef;\r
59   @ViewChild('properties') propertiesElement: ElementRef;\r
60   @ViewChild('handle') handleElement: ElementRef;\r
61 \r
62   @ViewChild('testDefinitionForm') form: any;\r
63   @ViewChild('scripts') scripts: ElementRef;\r
64   @ViewChild('file') bpmnFileInput: ElementRef;\r
65 \r
66   public qpTestDefinitionId;\r
67 \r
68   public ptd: TestDefinitionElement;\r
69   public uploader: FileUploader;\r
70   public bpmnUploader: FileUploader;\r
71   public pStatus: String;\r
72   public inProgress: Boolean;\r
73   public groups: Array<Group>;\r
74   public modeler: Bpmn;\r
75   public showProperties = true;\r
76   public isResizing = false;\r
77   public lastDownX = 0;\r
78   public propertiesWidth = '500px';\r
79   public showSidebar = true;\r
80   public showTestDefinition = false;\r
81   public bpmnId; //javascript input element\r
82   public isRefreshed = false;\r
83   public hasBeenSaved: Boolean = false;\r
84 \r
85   constructor(\r
86     public _dialog: MatDialog,\r
87     private _testHeads: TestHeadService,\r
88     private _groups: GroupService,\r
89     private _testDefinitions: TestDefinitionService,\r
90     private _snack: MatSnackBar,\r
91     private _fileTransfer: FileTransferService,\r
92     private _route: ActivatedRoute,\r
93     private _router: Router,\r
94     private _bpmnFactory: BpmnFactoryService) {\r
95   }\r
96 \r
97   @HostListener('window:beforeunload', ['$event'])\r
98   canLeavePage($event) {\r
99     $event.preventDefault();\r
100     alert('are you sure')\r
101   }\r
102 \r
103   async ngOnInit() {\r
104 \r
105     this._route.queryParams.subscribe(res => {\r
106       if (res.testDefinitionId) {\r
107         this.qpTestDefinitionId = res.testDefinitionId;\r
108       } else {\r
109         this.qpTestDefinitionId = null;\r
110       }\r
111       this.setup();\r
112     })\r
113 \r
114     //set groups list\r
115     this._groups.find({\r
116       $limit: -1,\r
117       lookup: 'both'\r
118     }).subscribe(res => {\r
119       this.groups = res as Array<Group>;\r
120       this.groups = this._groups.organizeGroups(this.groups);\r
121       \r
122     });\r
123 \r
124   }\r
125 \r
126   async setup() {\r
127 \r
128     this.setInProgress(true);\r
129 \r
130     await this.setTestDefinition();\r
131 \r
132     const modelerOptions = {\r
133       container: this.modelerElement.nativeElement,\r
134       propertiesPanel: {\r
135         parent: '#properties'\r
136       },\r
137       elementTemplates: [vthTemplate],\r
138       additionalModules: [\r
139         minimapModule,\r
140         propertiesPanelModule,\r
141         propertiesProviderModule\r
142         // colorPickerModule,\r
143         // logTestResultDrawModule,\r
144         // logTestResultPaletteModule\r
145       ],\r
146       moddleExtensions: {\r
147         camunda: camundaModdleDescriptor\r
148       },\r
149       keyboard: {\r
150         bindTo: document\r
151       }\r
152     };\r
153 \r
154     // Set up empty modeler\r
155     await this.setModeler({\r
156       mode: 'modeler',\r
157       options: modelerOptions\r
158     });\r
159 \r
160     this.setBpmn(false);\r
161 \r
162     //set ups draggable properties container\r
163     $(this.handleElement.nativeElement).on('mousedown', e => {\r
164       this.lastDownX = e.clientX;\r
165       this.isResizing = true;\r
166     });\r
167 \r
168     $(document).on('mousemove', e => {\r
169       if (!this.isResizing)\r
170         return;\r
171 \r
172       var offsetRight = $(this.containerElement.nativeElement).width() - (e.clientX - $(this.containerElement.nativeElement).offset().left);\r
173 \r
174       $(this.modelerElement.nativeElement).css('right', offsetRight);\r
175       $(this.sidebarElement.nativeElement).css('width', offsetRight);\r
176     }).on('mouseup', e => {\r
177       this.isResizing = false;\r
178     });\r
179 \r
180 \r
181   }\r
182 \r
183   /*****************************************\r
184    * Form Functionality Methods\r
185    ****************************************/\r
186 \r
187   /*** BUTTONS ***/\r
188 \r
189   async newWorkflow() {\r
190     if (this.qpTestDefinitionId) {\r
191       this._router.navigate([], {\r
192         queryParams: {}\r
193       });\r
194     } else {\r
195       this.setup();\r
196     }\r
197   }\r
198 \r
199   async download() {\r
200     this.modeler.download();\r
201   }\r
202 \r
203   async save() {\r
204     this.setInProgress(true);\r
205     let validResult = await this.validateFile();\r
206 \r
207     if (validResult) {\r
208       if (this.hasBeenSaved) {\r
209         await this.updateDefinition();\r
210       } else {\r
211         let td = await this.saveDefinition();\r
212         this._router.navigate([], {\r
213           queryParams: {\r
214             testDefinitionId: td['_id']\r
215           }\r
216         });\r
217       }\r
218     }\r
219 \r
220     this.snackAlert('Version ' + this.ptd.currentVersionName + ' has been saved');\r
221     this.setInProgress(false);\r
222     this.markFormAs('pristine');\r
223   }\r
224 \r
225   async deploy(versionName?) {\r
226     this.inProgress = true;\r
227 \r
228     this._testDefinitions.deploy(this.ptd, versionName)\r
229       .subscribe(\r
230         result => {\r
231           this.inProgress = false;\r
232           if (result['statusCode'] == 200) {\r
233             this.snackAlert('Test Definition Deployed Successfully')\r
234             this.ptd.currentInstance.isDeployed = true;\r
235           } else {\r
236             this.errorPopup(result.toString());\r
237           }\r
238         },\r
239         err => {\r
240           this.errorPopup(err.toString());\r
241           this.setInProgress(false);\r
242         }\r
243 \r
244       );\r
245   }\r
246 \r
247   async deleteVersion() {\r
248     let deleteDialog = this._dialog.open(AlertModalComponent, {\r
249       width: '250px',\r
250       data: { type: 'confirmation', message: 'Are you sure you want to delete version ' + this.ptd.currentVersionName }\r
251     });\r
252 \r
253     deleteDialog.afterClosed().subscribe(\r
254       result => {\r
255         if (result) {\r
256           this.setInProgress(true);\r
257           if (this.ptd.bpmnInstances.length == 1) {\r
258             this._testDefinitions.delete(this.ptd._id).subscribe(\r
259               result => {\r
260                 this.snackAlert('Test definition was deleted');\r
261                 this.setInProgress(false);\r
262                 this.newWorkflow();\r
263               },\r
264               err => {\r
265                 this.setInProgress(false);\r
266                 this.errorPopup(err.toString());\r
267               }\r
268             )\r
269           } else {\r
270             let version = this.ptd.currentVersionName;\r
271             // if deleting a version from a definition that has more than 1 version\r
272             this.ptd.removeBpmnInstance(this.ptd.currentVersionName);\r
273 \r
274             //prepare patch request\r
275             let request = {\r
276               _id: this.ptd._id,\r
277               bpmnInstances: this.ptd.bpmnInstances\r
278             }\r
279 \r
280             this._testDefinitions.patch(request).subscribe(\r
281               res => {\r
282                 this.setVersion();\r
283                 this.setInProgress(false);\r
284                 this.snackAlert('Version ' + version + ' was deleted');\r
285               },\r
286               err => {\r
287                 this.setInProgress(false);\r
288                 this.errorPopup(err.toString());\r
289               }\r
290             );\r
291           }\r
292         }\r
293       }\r
294     )\r
295   }\r
296 \r
297 \r
298   /*** UTILITY METHODS ***/\r
299 \r
300   //Looks for the definition supplied in the url, or pulls up default workflow\r
301   async setTestDefinition() {\r
302     return new Promise((resolve, reject) => {\r
303       if (this.qpTestDefinitionId) {\r
304         this._testDefinitions.get(this.qpTestDefinitionId).subscribe(\r
305           result => {\r
306             \r
307             this.ptd = new TestDefinitionElement();\r
308             this.ptd.setAll(result);\r
309             this.setAsSaved(true);\r
310             resolve(this.ptd);\r
311           },\r
312           err => {\r
313             this.errorPopup(err.toString());\r
314             reject(err);\r
315           }\r
316         )\r
317       } else {\r
318         //set new test definition\r
319         this.ptd = new TestDefinitionElement();\r
320         resolve(this.ptd);\r
321       }\r
322     });\r
323 \r
324   }\r
325 \r
326   //will set the selected version. If no version is given, the latest will be selected\r
327   async setVersion(version?) {\r
328 \r
329     //if version not supplied, grab latest\r
330     this.ptd.switchVersion(version);\r
331 \r
332     this.setBpmn(true);\r
333 \r
334   }\r
335 \r
336 \r
337 \r
338   async newVersion(options?: NewVersionOptions) {\r
339 \r
340     if (options && options.versionIndex != null) {\r
341 \r
342       //create new instance and copy xml\r
343       let instance = this.ptd.newInstance();\r
344       instance.bpmnFileId = this.ptd.bpmnInstances[options.versionIndex].bpmnFileId;\r
345       instance.bpmnXml = this.ptd.bpmnInstances[options.versionIndex].bpmnXml;\r
346 \r
347       this.ptd.addBpmnInstance(instance);\r
348 \r
349     } else if ( options && options.fromFile) {\r
350       \r
351       let instance = this.ptd.newInstance();\r
352 \r
353       instance.bpmnFileId = '0';\r
354       let xml = await new Promise((resolve, reject) => {\r
355         this.fetchFileContents('fileForVersion', xml => {\r
356           resolve(xml);\r
357         });\r
358       });\r
359 \r
360       instance.bpmnXml = xml as String;\r
361 \r
362       //set the files process definition key\r
363       let parser = new DOMParser();\r
364       let xmlDoc = parser.parseFromString(instance.bpmnXml.toString(), "text/xml");\r
365       //set the process definition key in xml\r
366       xmlDoc.getElementsByTagName("bpmn:process")[0].attributes.getNamedItem("id").value = this.ptd.processDefinitionKey as string;\r
367       //save the xml\r
368       instance.bpmnXml = (new XMLSerializer()).serializeToString(xmlDoc);\r
369 \r
370       this.ptd.addBpmnInstance(instance);\r
371 \r
372     } else {\r
373       this.ptd.addBpmnInstance();\r
374     }\r
375 \r
376     this.setVersion();\r
377     this.markFormAs('dirty');\r
378     this.ptd.currentInstance.bpmnHasChanged = true;\r
379   }\r
380 \r
381   popup() {\r
382     \r
383   }\r
384 \r
385   async validateFile() {\r
386     return new Promise((resolve, reject) => {\r
387 \r
388       this.modeler.getBpmnXml().then(xml => {\r
389 \r
390         this.ptd.currentInstance.bpmnXml = xml.toString();\r
391 \r
392         this._testDefinitions.validate(this.ptd)\r
393           .subscribe(\r
394             result => {\r
395 \r
396               if (result['body'].errors && result['body'].errors != {}) {\r
397                 this.errorPopup(JSON.stringify(result['body'].errors));\r
398                 resolve(false);\r
399               }\r
400               //this.handleResponse(result, false);\r
401               //this.ptd.currentInstance.bpmnHasChanged = true;\r
402 \r
403               // If any VTH or PFLOs were detected, add to object\r
404               // Update list of test heads\r
405               if (result['body']['bpmnVthTaskIds']) {\r
406                 this.ptd.currentInstance.testHeads = result['body'].bpmnVthTaskIds;\r
407                 this.ptd.currentInstance.testHeads.forEach((elem, val) => {\r
408                   this.ptd.currentInstance.testHeads[val]['testHeadId'] = elem['testHead']._id;\r
409                   delete this.ptd.currentInstance.testHeads[val]['testHead'];\r
410                 })\r
411 \r
412               }\r
413 \r
414               //Update plfos list\r
415               if(result['body']['bpmnPfloTaskIds']){\r
416                 this.ptd.currentInstance.pflos = result['body'].bpmnPfloTaskIds;\r
417               }\r
418 \r
419               resolve(true);\r
420             },\r
421             err => {\r
422               reject(false);\r
423             }\r
424           );\r
425 \r
426       }).catch(err => {\r
427         this.errorPopup(err);\r
428       });\r
429 \r
430     });\r
431 \r
432   }\r
433 \r
434   //returns promise for file object \r
435   async saveBpmnFile() {\r
436     return new Promise((resolve, reject) => {\r
437 \r
438       this.modeler.getBpmnXml().then(\r
439         res => {\r
440           this.ptd.currentInstance.bpmnXml = res as String;\r
441           this._testDefinitions.validateSave(this.ptd).subscribe(\r
442             result => {\r
443               resolve(JSON.parse(result.toString())[0]._id);\r
444             },\r
445             err => {\r
446               this.errorPopup(err.toString());\r
447               reject(err);\r
448             }\r
449           )\r
450         }\r
451       )\r
452     });\r
453   }\r
454 \r
455   async saveDefinition() {\r
456 \r
457     return new Promise(async (resolve, reject) => {\r
458       \r
459       let fileId = await this.saveBpmnFile();\r
460 \r
461       if (fileId) {\r
462         this.ptd.currentInstance.bpmnFileId = fileId as String;\r
463       }\r
464 \r
465       delete this.ptd._id;\r
466       \r
467       this._testDefinitions.create(this.ptd).subscribe(\r
468         res => {\r
469           \r
470           resolve(res);\r
471         },\r
472         err => {\r
473           this.errorPopup(err.message);\r
474           this.setInProgress(false);\r
475           reject(err);\r
476         }\r
477       )\r
478     });\r
479 \r
480   }\r
481 \r
482   async updateDefinition() {\r
483     return new Promise(async (resolve, reject) => {\r
484 \r
485       let versionIndex = this.ptd.currentVersion;\r
486 \r
487       // set parameters to be sent with the patch\r
488       let request = {\r
489         _id: this.ptd._id,\r
490         testName: this.ptd.testName,\r
491         testDescription: this.ptd.testDescription,\r
492         groupId: this.ptd.groupId\r
493       }\r
494 \r
495       // If xml has changed, upload file and patch definition details, else just updated details\r
496       if (this.ptd.currentInstance.bpmnHasChanged) {\r
497 \r
498         //upload file\r
499         let fileId = await this.saveBpmnFile();\r
500 \r
501         //set file id in the bpmn instance\r
502         if (fileId) {\r
503           this.ptd.currentInstance.bpmnFileId = fileId as String;\r
504         }\r
505       }\r
506 \r
507       //check if this bpmn version has been saved, else its a new version\r
508       if (this.ptd.currentInstance.createdAt) {\r
509         this.ptd.currentInstance.updatedAt = new Date().toISOString();\r
510         request['bpmnInstances.' + this.ptd.currentVersion] = this.ptd.currentInstance;\r
511       } else {\r
512         this.ptd.currentInstance.createdAt = new Date().toISOString();\r
513         this.ptd.currentInstance.updatedAt = new Date().toISOString();\r
514         request['$push'] = {\r
515           bpmnInstances: this.ptd.currentInstance\r
516         }\r
517       }\r
518 \r
519       //patch with updated fields\r
520       this._testDefinitions.patch(request).subscribe(res => {\r
521         this.ptd.currentInstance.bpmnHasChanged = false;\r
522         resolve(res);\r
523       },\r
524         err => {\r
525           reject(err);\r
526         });\r
527     });\r
528   }\r
529 \r
530   markFormAs(mode: 'dirty' | 'pristine') {\r
531     if (mode == 'dirty') {\r
532       this.form.control.markAsDirty();\r
533     } else {\r
534       this.form.control.markAsPristine();\r
535     }\r
536   }\r
537 \r
538 \r
539   async checkProcessDefinitionKey() {\r
540     let foundDefinition = null;\r
541     \r
542     this._testDefinitions.check(this.ptd.processDefinitionKey).subscribe(async result => {\r
543       if (result['statusCode'] == 200) {\r
544         this.pStatus = 'unique';\r
545       } else {\r
546         this.pStatus = 'notUnique';\r
547       }\r
548       \r
549 \r
550       //If process definition key found\r
551       if (result['body'] && result['body'][0]) {\r
552 \r
553         foundDefinition = result['body'][0];\r
554 \r
555       } else {\r
556         //seach mongodb for td with pdk\r
557         await new Promise((resolve, reject) => {\r
558           this._testDefinitions.find({\r
559             processDefinitionKey: this.ptd.processDefinitionKey\r
560           }).subscribe(res => {\r
561             \r
562             if (res['total'] > 0) {\r
563               foundDefinition = res['data'][0];\r
564             }\r
565             resolve()\r
566           }, err => {\r
567             reject();\r
568           })\r
569         });\r
570       }\r
571       \r
572       if (foundDefinition) {\r
573         if (this.qpTestDefinitionId != foundDefinition._id) {\r
574           let confirm = this._dialog.open(AlertModalComponent, {\r
575             width: '400px',\r
576             data: {\r
577               type: 'confirmation',\r
578               message: 'The process definition key "' + this.ptd.processDefinitionKey + '" already exists. Would you like to load the test definition, ' + foundDefinition.testName + ' ? This will delete any unsaved work.'\r
579             }\r
580           });\r
581 \r
582           confirm.afterClosed().subscribe(doChange => {\r
583             if (doChange) {\r
584               this._router.navigate([], {\r
585                 queryParams: {\r
586                   testDefinitionId: foundDefinition._id\r
587                 }\r
588               })\r
589             } else {\r
590               this.bpmnId.value = '';\r
591             }\r
592           })\r
593         }\r
594       } else {\r
595         let tempPK = this.ptd.processDefinitionKey;\r
596         this.ptd.reset();\r
597 \r
598         this.ptd.setProcessDefinitionKey(tempPK);\r
599 \r
600         this.ptd.setId(null);\r
601         this.ptd.setName('');\r
602         this.ptd.setDescription('');\r
603         this.ptd.setGroupId('');\r
604         this.ptd.setVersion(1);\r
605         this.setAsSaved(false);\r
606       }\r
607 \r
608       if (!this.ptd.currentInstance.version) {\r
609         this.ptd.setNewVersion();\r
610       }\r
611 \r
612       this.markFormAs('pristine');\r
613 \r
614       this.ptd.currentInstance.bpmnHasChanged = false;\r
615 \r
616 \r
617     });\r
618   }\r
619 \r
620   setInProgress(mode: Boolean) {\r
621     this.inProgress = mode;\r
622   }\r
623 \r
624   setAsSaved(mode: Boolean) {\r
625     this.hasBeenSaved = mode;\r
626   }\r
627 \r
628   /*****************************************\r
629    * BPMN Modeler Functions\r
630    ****************************************/\r
631 \r
632   async setBpmn(isNewVersion: Boolean, xml?) {\r
633 \r
634     //If a test definition is loaded set bpmnXml with latest version, else set default flow\r
635     if (xml) {\r
636       this.ptd.currentInstance.bpmnXml = xml;\r
637     } else {\r
638       if (this.ptd._id && this.ptd.currentInstance.bpmnFileId) {\r
639         if (!this.ptd.currentInstance.bpmnXml) {\r
640           this.ptd.currentInstance.bpmnXml = await this.getVersionBpmn() as String;\r
641         }\r
642       } else {\r
643         this.ptd.currentInstance.bpmnXml = await this.getDefaultFlow() as String;\r
644 \r
645         // If it is a blank new version, set the process definition key in xml\r
646         if (isNewVersion) {\r
647           let parser = new DOMParser();\r
648           //Parse xml\r
649           let xmlDoc = parser.parseFromString(this.ptd.currentInstance.bpmnXml.toString(), "text/xml");\r
650           //set the process definition key in xml\r
651           xmlDoc.getElementsByTagName("bpmn:process")[0].attributes.getNamedItem("id").value = this.ptd.processDefinitionKey as string;\r
652           //save the xml\r
653           this.ptd.currentInstance.bpmnXml = (new XMLSerializer()).serializeToString(xmlDoc);\r
654 \r
655         }\r
656       }\r
657     }\r
658 \r
659     await this.modeler.setBpmnXml(this.ptd.currentInstance.bpmnXml);\r
660 \r
661     //Set bpmn id\r
662     this.bpmnId = (<HTMLInputElement>document.getElementById("camunda-id"));\r
663 \r
664     if (!isNewVersion) {\r
665       //Set process Definition key\r
666       this.ptd.processDefinitionKey = this.bpmnId.value;\r
667 \r
668       //Check the process Definition key to get its test definition loaded in.\r
669       \r
670       this.checkProcessDefinitionKey();\r
671     }\r
672 \r
673     //Listen for any changes made to the diagram and properties panel\r
674     this.modeler.getModel().on('element.changed', (event) => {\r
675       //check to see if process definition key has changed\r
676       if (event.element.type == 'bpmn:Process' && (this.ptd.processDefinitionKey != event.element.id)) {\r
677         this.ptd.processDefinitionKey = event.element.id;\r
678         this.checkProcessDefinitionKey();\r
679       }\r
680 \r
681       // If it has been deployed, they cannot edit and save it\r
682       if (!this.ptd.currentInstance.isDeployed) {\r
683         this.ptd.currentInstance.bpmnHasChanged = true;\r
684         this.markFormAs('dirty');\r
685       }\r
686     });\r
687 \r
688     this.setInProgress(false);\r
689 \r
690   }\r
691 \r
692   //Open a .bpmn file\r
693   async open() {\r
694 \r
695     this.setInProgress(true);\r
696     this.ptd.reset();\r
697     this.ptd.switchVersion();\r
698 \r
699     this.fetchFileContents('file', val => {\r
700       this.setBpmn(false, val);\r
701     });\r
702 \r
703   }\r
704 \r
705   //Get the xml of the default bpmn file\r
706   async getDefaultFlow() {\r
707     return new Promise((resolve, reject) => {\r
708       this._fileTransfer.get('5d0a5357e6624a3ef0d16164').subscribe(\r
709         data => {\r
710           let bpmn = new Buffer(data as Buffer);\r
711           resolve(bpmn.toString());\r
712         },\r
713         err => {\r
714           this.errorPopup(err.toString());\r
715           reject(err);\r
716         }\r
717       );\r
718     });\r
719   }\r
720 \r
721   //set the Modeler\r
722   async setModeler(options) {\r
723     if (!this.modeler) {\r
724       this.modeler = await this._bpmnFactory.setup(options);\r
725     }\r
726   }\r
727 \r
728   async getVersionBpmn() {\r
729     return new Promise((resolve, reject) => {\r
730       this._fileTransfer.get(this.ptd.currentInstance.bpmnFileId).subscribe(\r
731         result => {\r
732           let bpmn = new Buffer(result as Buffer);\r
733           resolve(bpmn.toString());\r
734         },\r
735         err => {\r
736           this.errorPopup(err.toString());\r
737           reject(err);\r
738         }\r
739       );\r
740     });\r
741   }\r
742 \r
743   fetchFileContents(elementId, callback) {\r
744     var val = "x";\r
745     var fileToLoad = (document.getElementById(elementId))['files'][0];\r
746     var fileReader = new FileReader();\r
747     if (!fileToLoad) {\r
748       return null;\r
749     }\r
750 \r
751     fileReader.onload = function (event) {\r
752       val = event.target['result'] as string;\r
753       callback(val);\r
754     }\r
755     fileReader.readAsText(fileToLoad);\r
756   }\r
757 \r
758   /*****************************************\r
759    * Page Funtionality Methods\r
760    ****************************************/\r
761 \r
762   toggleSidebar(set: Boolean) {\r
763     if (!set) {\r
764       this.showSidebar = false;\r
765       this.modelerElement.nativeElement.style.right = '0px';\r
766     } else {\r
767       this.showSidebar = true;\r
768       $(this.modelerElement.nativeElement).css('right', $(this.sidebarElement.nativeElement).width());\r
769     }\r
770   }\r
771 \r
772   toggleProperties() {\r
773     if (!this.showProperties) {\r
774       this.toggleSidebar(true);\r
775       this.showTestDefinition = false;\r
776       this.showProperties = true;\r
777     } else {\r
778       this.toggleSidebar(false);\r
779       this.showProperties = false;\r
780     }\r
781   }\r
782 \r
783   toggleTestDefinition() {\r
784     if (!this.showTestDefinition) {\r
785       this.toggleSidebar(true);\r
786       this.showProperties = false;\r
787       this.showTestDefinition = true;\r
788     } else {\r
789       this.toggleSidebar(false);\r
790       this.showTestDefinition = false;\r
791     }\r
792 \r
793     this.refresh();\r
794   }\r
795 \r
796   refresh() {\r
797     this.isRefreshed = false;\r
798     setTimeout(() => {\r
799       this.isRefreshed = true;\r
800     }, 1);\r
801   }\r
802 \r
803   snackAlert(msg) {\r
804     this._snack.openFromComponent(AlertSnackbarComponent, {\r
805       duration: 1500,\r
806       data: {\r
807         message: msg\r
808       }\r
809     });\r
810   }\r
811 \r
812   errorPopup(err) {\r
813     return this._dialog.open(AlertModalComponent, {\r
814       width: '400px',\r
815       data: {\r
816         type: 'alert',\r
817         message: err\r
818       }\r
819     });\r
820   }\r
821 }\r