--- /dev/null
+/* Copyright (c) 2019 AT&T Intellectual Property. #\r
+# #\r
+# Licensed under the Apache License, Version 2.0 (the "License"); #\r
+# you may not use this file except in compliance with the License. #\r
+# You may obtain a copy of the License at #\r
+# #\r
+# http://www.apache.org/licenses/LICENSE-2.0 #\r
+# #\r
+# Unless required by applicable law or agreed to in writing, software #\r
+# distributed under the License is distributed on an "AS IS" BASIS, #\r
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #\r
+# See the License for the specific language governing permissions and #\r
+# limitations under the License. #\r
+##############################################################################*/\r
+\r
+\r
+import { Component, OnInit, ViewChild, ElementRef, AfterViewInit, HostListener } from '@angular/core';\r
+import minimapModule from 'diagram-js-minimap';\r
+import { FileTransferService } from 'app/shared/services/file-transfer.service';\r
+import { Buffer } from 'buffer';\r
+import propertiesPanelModule from 'bpmn-js-properties-panel';\r
+import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda';\r
+import * as camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda.json';\r
+import * as vthTemplate from './templates/elements.json';\r
+import * as $ from 'jquery';\r
+import { MatDialog, MatSnackBar } from '@angular/material';\r
+import { TestHeadService } from 'app/shared/services/test-head.service';\r
+import { GroupService } from 'app/shared/services/group.service';\r
+import { TestDefinitionService } from 'app/shared/services/test-definition.service';\r
+import { CookieService } from 'ngx-cookie-service';\r
+import { FileService } from 'app/shared/services/file.service';\r
+import { ActivatedRoute, Router } from '@angular/router';\r
+import { BpmnFactoryService } from 'app/shared/factories/bpmn-factory.service';\r
+import { Bpmn } from 'app/shared/models/bpmn.model';\r
+import { TestDefinitionElement, BpmnInstanceElement } from './test-definition-element.class.js';\r
+import { FileUploader } from 'ng2-file-upload';\r
+import { Group } from 'app/shared/models/group.model.js';\r
+import { AlertSnackbarComponent } from 'app/shared/modules/alert-snackbar/alert-snackbar.component';\r
+import { AlertModalComponent } from 'app/shared/modules/alert-modal/alert-modal.component';\r
+\r
+interface NewVersionOptions {\r
+ versionIndex: number,\r
+ fromFile: Boolean\r
+}\r
+\r
+@Component({\r
+ selector: 'app-modeler',\r
+ templateUrl: './modeler.component.pug',\r
+ styleUrls: [\r
+ './modeler.component.scss',\r
+ ]\r
+})\r
+\r
+export class ModelerComponent implements OnInit {\r
+\r
+ @ViewChild('container') containerElement: ElementRef;\r
+ @ViewChild('modeler') modelerElement: ElementRef;\r
+ @ViewChild('sidebar') sidebarElement: ElementRef;\r
+ @ViewChild('properties') propertiesElement: ElementRef;\r
+ @ViewChild('handle') handleElement: ElementRef;\r
+\r
+ @ViewChild('testDefinitionForm') form: any;\r
+ @ViewChild('scripts') scripts: ElementRef;\r
+ @ViewChild('file') bpmnFileInput: ElementRef;\r
+\r
+ public qpTestDefinitionId;\r
+\r
+ public ptd: TestDefinitionElement;\r
+ public uploader: FileUploader;\r
+ public bpmnUploader: FileUploader;\r
+ public pStatus: String;\r
+ public inProgress: Boolean;\r
+ public groups: Array<Group>;\r
+ public modeler: Bpmn;\r
+ public showProperties = true;\r
+ public isResizing = false;\r
+ public lastDownX = 0;\r
+ public propertiesWidth = '500px';\r
+ public showSidebar = true;\r
+ public showTestDefinition = false;\r
+ public bpmnId; //javascript input element\r
+ public isRefreshed = false;\r
+ public hasBeenSaved: Boolean = false;\r
+\r
+ constructor(\r
+ public _dialog: MatDialog,\r
+ private _testHeads: TestHeadService,\r
+ private _groups: GroupService,\r
+ private _testDefinitions: TestDefinitionService,\r
+ private _snack: MatSnackBar,\r
+ private _fileTransfer: FileTransferService,\r
+ private _route: ActivatedRoute,\r
+ private _router: Router,\r
+ private _bpmnFactory: BpmnFactoryService) {\r
+ }\r
+\r
+ @HostListener('window:beforeunload', ['$event'])\r
+ canLeavePage($event) {\r
+ $event.preventDefault();\r
+ alert('are you sure')\r
+ }\r
+\r
+ async ngOnInit() {\r
+\r
+ this._route.queryParams.subscribe(res => {\r
+ if (res.testDefinitionId) {\r
+ this.qpTestDefinitionId = res.testDefinitionId;\r
+ } else {\r
+ this.qpTestDefinitionId = null;\r
+ }\r
+ this.setup();\r
+ })\r
+\r
+ //set groups list\r
+ this._groups.find({\r
+ $limit: -1,\r
+ lookup: 'both'\r
+ }).subscribe(res => {\r
+ this.groups = res as Array<Group>;\r
+ this.groups = this._groups.organizeGroups(this.groups);\r
+ \r
+ });\r
+\r
+ }\r
+\r
+ async setup() {\r
+\r
+ this.setInProgress(true);\r
+\r
+ await this.setTestDefinition();\r
+\r
+ const modelerOptions = {\r
+ container: this.modelerElement.nativeElement,\r
+ propertiesPanel: {\r
+ parent: '#properties'\r
+ },\r
+ elementTemplates: [vthTemplate],\r
+ additionalModules: [\r
+ minimapModule,\r
+ propertiesPanelModule,\r
+ propertiesProviderModule\r
+ // colorPickerModule,\r
+ // logTestResultDrawModule,\r
+ // logTestResultPaletteModule\r
+ ],\r
+ moddleExtensions: {\r
+ camunda: camundaModdleDescriptor\r
+ },\r
+ keyboard: {\r
+ bindTo: document\r
+ }\r
+ };\r
+\r
+ // Set up empty modeler\r
+ await this.setModeler({\r
+ mode: 'modeler',\r
+ options: modelerOptions\r
+ });\r
+\r
+ this.setBpmn(false);\r
+\r
+ //set ups draggable properties container\r
+ $(this.handleElement.nativeElement).on('mousedown', e => {\r
+ this.lastDownX = e.clientX;\r
+ this.isResizing = true;\r
+ });\r
+\r
+ $(document).on('mousemove', e => {\r
+ if (!this.isResizing)\r
+ return;\r
+\r
+ var offsetRight = $(this.containerElement.nativeElement).width() - (e.clientX - $(this.containerElement.nativeElement).offset().left);\r
+\r
+ $(this.modelerElement.nativeElement).css('right', offsetRight);\r
+ $(this.sidebarElement.nativeElement).css('width', offsetRight);\r
+ }).on('mouseup', e => {\r
+ this.isResizing = false;\r
+ });\r
+\r
+\r
+ }\r
+\r
+ /*****************************************\r
+ * Form Functionality Methods\r
+ ****************************************/\r
+\r
+ /*** BUTTONS ***/\r
+\r
+ async newWorkflow() {\r
+ if (this.qpTestDefinitionId) {\r
+ this._router.navigate([], {\r
+ queryParams: {}\r
+ });\r
+ } else {\r
+ this.setup();\r
+ }\r
+ }\r
+\r
+ async download() {\r
+ this.modeler.download();\r
+ }\r
+\r
+ async save() {\r
+ this.setInProgress(true);\r
+ let validResult = await this.validateFile();\r
+\r
+ if (validResult) {\r
+ if (this.hasBeenSaved) {\r
+ await this.updateDefinition();\r
+ } else {\r
+ let td = await this.saveDefinition();\r
+ this._router.navigate([], {\r
+ queryParams: {\r
+ testDefinitionId: td['_id']\r
+ }\r
+ });\r
+ }\r
+ }\r
+\r
+ this.snackAlert('Version ' + this.ptd.currentVersionName + ' has been saved');\r
+ this.setInProgress(false);\r
+ this.markFormAs('pristine');\r
+ }\r
+\r
+ async deploy(versionName?) {\r
+ this.inProgress = true;\r
+\r
+ this._testDefinitions.deploy(this.ptd, versionName)\r
+ .subscribe(\r
+ result => {\r
+ this.inProgress = false;\r
+ if (result['statusCode'] == 200) {\r
+ this.snackAlert('Test Definition Deployed Successfully')\r
+ this.ptd.currentInstance.isDeployed = true;\r
+ } else {\r
+ this.errorPopup(result.toString());\r
+ }\r
+ },\r
+ err => {\r
+ this.errorPopup(err.toString());\r
+ this.setInProgress(false);\r
+ }\r
+\r
+ );\r
+ }\r
+\r
+ async deleteVersion() {\r
+ let deleteDialog = this._dialog.open(AlertModalComponent, {\r
+ width: '250px',\r
+ data: { type: 'confirmation', message: 'Are you sure you want to delete version ' + this.ptd.currentVersionName }\r
+ });\r
+\r
+ deleteDialog.afterClosed().subscribe(\r
+ result => {\r
+ if (result) {\r
+ this.setInProgress(true);\r
+ if (this.ptd.bpmnInstances.length == 1) {\r
+ this._testDefinitions.delete(this.ptd._id).subscribe(\r
+ result => {\r
+ this.snackAlert('Test definition was deleted');\r
+ this.setInProgress(false);\r
+ this.newWorkflow();\r
+ },\r
+ err => {\r
+ this.setInProgress(false);\r
+ this.errorPopup(err.toString());\r
+ }\r
+ )\r
+ } else {\r
+ let version = this.ptd.currentVersionName;\r
+ // if deleting a version from a definition that has more than 1 version\r
+ this.ptd.removeBpmnInstance(this.ptd.currentVersionName);\r
+\r
+ //prepare patch request\r
+ let request = {\r
+ _id: this.ptd._id,\r
+ bpmnInstances: this.ptd.bpmnInstances\r
+ }\r
+\r
+ this._testDefinitions.patch(request).subscribe(\r
+ res => {\r
+ this.setVersion();\r
+ this.setInProgress(false);\r
+ this.snackAlert('Version ' + version + ' was deleted');\r
+ },\r
+ err => {\r
+ this.setInProgress(false);\r
+ this.errorPopup(err.toString());\r
+ }\r
+ );\r
+ }\r
+ }\r
+ }\r
+ )\r
+ }\r
+\r
+\r
+ /*** UTILITY METHODS ***/\r
+\r
+ //Looks for the definition supplied in the url, or pulls up default workflow\r
+ async setTestDefinition() {\r
+ return new Promise((resolve, reject) => {\r
+ if (this.qpTestDefinitionId) {\r
+ this._testDefinitions.get(this.qpTestDefinitionId).subscribe(\r
+ result => {\r
+ \r
+ this.ptd = new TestDefinitionElement();\r
+ this.ptd.setAll(result);\r
+ this.setAsSaved(true);\r
+ resolve(this.ptd);\r
+ },\r
+ err => {\r
+ this.errorPopup(err.toString());\r
+ reject(err);\r
+ }\r
+ )\r
+ } else {\r
+ //set new test definition\r
+ this.ptd = new TestDefinitionElement();\r
+ resolve(this.ptd);\r
+ }\r
+ });\r
+\r
+ }\r
+\r
+ //will set the selected version. If no version is given, the latest will be selected\r
+ async setVersion(version?) {\r
+\r
+ //if version not supplied, grab latest\r
+ this.ptd.switchVersion(version);\r
+\r
+ this.setBpmn(true);\r
+\r
+ }\r
+\r
+\r
+\r
+ async newVersion(options?: NewVersionOptions) {\r
+\r
+ if (options && options.versionIndex != null) {\r
+\r
+ //create new instance and copy xml\r
+ let instance = this.ptd.newInstance();\r
+ instance.bpmnFileId = this.ptd.bpmnInstances[options.versionIndex].bpmnFileId;\r
+ instance.bpmnXml = this.ptd.bpmnInstances[options.versionIndex].bpmnXml;\r
+\r
+ this.ptd.addBpmnInstance(instance);\r
+\r
+ } else if ( options && options.fromFile) {\r
+ \r
+ let instance = this.ptd.newInstance();\r
+\r
+ instance.bpmnFileId = '0';\r
+ let xml = await new Promise((resolve, reject) => {\r
+ this.fetchFileContents('fileForVersion', xml => {\r
+ resolve(xml);\r
+ });\r
+ });\r
+\r
+ instance.bpmnXml = xml as String;\r
+\r
+ //set the files process definition key\r
+ let parser = new DOMParser();\r
+ let xmlDoc = parser.parseFromString(instance.bpmnXml.toString(), "text/xml");\r
+ //set the process definition key in xml\r
+ xmlDoc.getElementsByTagName("bpmn:process")[0].attributes.getNamedItem("id").value = this.ptd.processDefinitionKey as string;\r
+ //save the xml\r
+ instance.bpmnXml = (new XMLSerializer()).serializeToString(xmlDoc);\r
+\r
+ this.ptd.addBpmnInstance(instance);\r
+\r
+ } else {\r
+ this.ptd.addBpmnInstance();\r
+ }\r
+\r
+ this.setVersion();\r
+ this.markFormAs('dirty');\r
+ this.ptd.currentInstance.bpmnHasChanged = true;\r
+ }\r
+\r
+ popup() {\r
+ \r
+ }\r
+\r
+ async validateFile() {\r
+ return new Promise((resolve, reject) => {\r
+\r
+ this.modeler.getBpmnXml().then(xml => {\r
+\r
+ this.ptd.currentInstance.bpmnXml = xml.toString();\r
+\r
+ this._testDefinitions.validate(this.ptd)\r
+ .subscribe(\r
+ result => {\r
+\r
+ if (result['body'].errors && result['body'].errors != {}) {\r
+ this.errorPopup(JSON.stringify(result['body'].errors));\r
+ resolve(false);\r
+ }\r
+ //this.handleResponse(result, false);\r
+ //this.ptd.currentInstance.bpmnHasChanged = true;\r
+\r
+ // If any VTH or PFLOs were detected, add to object\r
+ // Update list of test heads\r
+ if (result['body']['bpmnVthTaskIds']) {\r
+ this.ptd.currentInstance.testHeads = result['body'].bpmnVthTaskIds;\r
+ this.ptd.currentInstance.testHeads.forEach((elem, val) => {\r
+ this.ptd.currentInstance.testHeads[val]['testHeadId'] = elem['testHead']._id;\r
+ delete this.ptd.currentInstance.testHeads[val]['testHead'];\r
+ })\r
+\r
+ }\r
+\r
+ //Update plfos list\r
+ if(result['body']['bpmnPfloTaskIds']){\r
+ this.ptd.currentInstance.pflos = result['body'].bpmnPfloTaskIds;\r
+ }\r
+\r
+ resolve(true);\r
+ },\r
+ err => {\r
+ reject(false);\r
+ }\r
+ );\r
+\r
+ }).catch(err => {\r
+ this.errorPopup(err);\r
+ });\r
+\r
+ });\r
+\r
+ }\r
+\r
+ //returns promise for file object \r
+ async saveBpmnFile() {\r
+ return new Promise((resolve, reject) => {\r
+\r
+ this.modeler.getBpmnXml().then(\r
+ res => {\r
+ this.ptd.currentInstance.bpmnXml = res as String;\r
+ this._testDefinitions.validateSave(this.ptd).subscribe(\r
+ result => {\r
+ resolve(JSON.parse(result.toString())[0]._id);\r
+ },\r
+ err => {\r
+ this.errorPopup(err.toString());\r
+ reject(err);\r
+ }\r
+ )\r
+ }\r
+ )\r
+ });\r
+ }\r
+\r
+ async saveDefinition() {\r
+\r
+ return new Promise(async (resolve, reject) => {\r
+ \r
+ let fileId = await this.saveBpmnFile();\r
+\r
+ if (fileId) {\r
+ this.ptd.currentInstance.bpmnFileId = fileId as String;\r
+ }\r
+\r
+ delete this.ptd._id;\r
+ \r
+ this._testDefinitions.create(this.ptd).subscribe(\r
+ res => {\r
+ \r
+ resolve(res);\r
+ },\r
+ err => {\r
+ this.errorPopup(err.message);\r
+ this.setInProgress(false);\r
+ reject(err);\r
+ }\r
+ )\r
+ });\r
+\r
+ }\r
+\r
+ async updateDefinition() {\r
+ return new Promise(async (resolve, reject) => {\r
+\r
+ let versionIndex = this.ptd.currentVersion;\r
+\r
+ // set parameters to be sent with the patch\r
+ let request = {\r
+ _id: this.ptd._id,\r
+ testName: this.ptd.testName,\r
+ testDescription: this.ptd.testDescription,\r
+ groupId: this.ptd.groupId\r
+ }\r
+\r
+ // If xml has changed, upload file and patch definition details, else just updated details\r
+ if (this.ptd.currentInstance.bpmnHasChanged) {\r
+\r
+ //upload file\r
+ let fileId = await this.saveBpmnFile();\r
+\r
+ //set file id in the bpmn instance\r
+ if (fileId) {\r
+ this.ptd.currentInstance.bpmnFileId = fileId as String;\r
+ }\r
+ }\r
+\r
+ //check if this bpmn version has been saved, else its a new version\r
+ if (this.ptd.currentInstance.createdAt) {\r
+ this.ptd.currentInstance.updatedAt = new Date().toISOString();\r
+ request['bpmnInstances.' + this.ptd.currentVersion] = this.ptd.currentInstance;\r
+ } else {\r
+ this.ptd.currentInstance.createdAt = new Date().toISOString();\r
+ this.ptd.currentInstance.updatedAt = new Date().toISOString();\r
+ request['$push'] = {\r
+ bpmnInstances: this.ptd.currentInstance\r
+ }\r
+ }\r
+\r
+ //patch with updated fields\r
+ this._testDefinitions.patch(request).subscribe(res => {\r
+ this.ptd.currentInstance.bpmnHasChanged = false;\r
+ resolve(res);\r
+ },\r
+ err => {\r
+ reject(err);\r
+ });\r
+ });\r
+ }\r
+\r
+ markFormAs(mode: 'dirty' | 'pristine') {\r
+ if (mode == 'dirty') {\r
+ this.form.control.markAsDirty();\r
+ } else {\r
+ this.form.control.markAsPristine();\r
+ }\r
+ }\r
+\r
+\r
+ async checkProcessDefinitionKey() {\r
+ let foundDefinition = null;\r
+ \r
+ this._testDefinitions.check(this.ptd.processDefinitionKey).subscribe(async result => {\r
+ if (result['statusCode'] == 200) {\r
+ this.pStatus = 'unique';\r
+ } else {\r
+ this.pStatus = 'notUnique';\r
+ }\r
+ \r
+\r
+ //If process definition key found\r
+ if (result['body'] && result['body'][0]) {\r
+\r
+ foundDefinition = result['body'][0];\r
+\r
+ } else {\r
+ //seach mongodb for td with pdk\r
+ await new Promise((resolve, reject) => {\r
+ this._testDefinitions.find({\r
+ processDefinitionKey: this.ptd.processDefinitionKey\r
+ }).subscribe(res => {\r
+ \r
+ if (res['total'] > 0) {\r
+ foundDefinition = res['data'][0];\r
+ }\r
+ resolve()\r
+ }, err => {\r
+ reject();\r
+ })\r
+ });\r
+ }\r
+ \r
+ if (foundDefinition) {\r
+ if (this.qpTestDefinitionId != foundDefinition._id) {\r
+ let confirm = this._dialog.open(AlertModalComponent, {\r
+ width: '400px',\r
+ data: {\r
+ type: 'confirmation',\r
+ 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
+ }\r
+ });\r
+\r
+ confirm.afterClosed().subscribe(doChange => {\r
+ if (doChange) {\r
+ this._router.navigate([], {\r
+ queryParams: {\r
+ testDefinitionId: foundDefinition._id\r
+ }\r
+ })\r
+ } else {\r
+ this.bpmnId.value = '';\r
+ }\r
+ })\r
+ }\r
+ } else {\r
+ let tempPK = this.ptd.processDefinitionKey;\r
+ this.ptd.reset();\r
+\r
+ this.ptd.setProcessDefinitionKey(tempPK);\r
+\r
+ this.ptd.setId(null);\r
+ this.ptd.setName('');\r
+ this.ptd.setDescription('');\r
+ this.ptd.setGroupId('');\r
+ this.ptd.setVersion(1);\r
+ this.setAsSaved(false);\r
+ }\r
+\r
+ if (!this.ptd.currentInstance.version) {\r
+ this.ptd.setNewVersion();\r
+ }\r
+\r
+ this.markFormAs('pristine');\r
+\r
+ this.ptd.currentInstance.bpmnHasChanged = false;\r
+\r
+\r
+ });\r
+ }\r
+\r
+ setInProgress(mode: Boolean) {\r
+ this.inProgress = mode;\r
+ }\r
+\r
+ setAsSaved(mode: Boolean) {\r
+ this.hasBeenSaved = mode;\r
+ }\r
+\r
+ /*****************************************\r
+ * BPMN Modeler Functions\r
+ ****************************************/\r
+\r
+ async setBpmn(isNewVersion: Boolean, xml?) {\r
+\r
+ //If a test definition is loaded set bpmnXml with latest version, else set default flow\r
+ if (xml) {\r
+ this.ptd.currentInstance.bpmnXml = xml;\r
+ } else {\r
+ if (this.ptd._id && this.ptd.currentInstance.bpmnFileId) {\r
+ if (!this.ptd.currentInstance.bpmnXml) {\r
+ this.ptd.currentInstance.bpmnXml = await this.getVersionBpmn() as String;\r
+ }\r
+ } else {\r
+ this.ptd.currentInstance.bpmnXml = await this.getDefaultFlow() as String;\r
+\r
+ // If it is a blank new version, set the process definition key in xml\r
+ if (isNewVersion) {\r
+ let parser = new DOMParser();\r
+ //Parse xml\r
+ let xmlDoc = parser.parseFromString(this.ptd.currentInstance.bpmnXml.toString(), "text/xml");\r
+ //set the process definition key in xml\r
+ xmlDoc.getElementsByTagName("bpmn:process")[0].attributes.getNamedItem("id").value = this.ptd.processDefinitionKey as string;\r
+ //save the xml\r
+ this.ptd.currentInstance.bpmnXml = (new XMLSerializer()).serializeToString(xmlDoc);\r
+\r
+ }\r
+ }\r
+ }\r
+\r
+ await this.modeler.setBpmnXml(this.ptd.currentInstance.bpmnXml);\r
+\r
+ //Set bpmn id\r
+ this.bpmnId = (<HTMLInputElement>document.getElementById("camunda-id"));\r
+\r
+ if (!isNewVersion) {\r
+ //Set process Definition key\r
+ this.ptd.processDefinitionKey = this.bpmnId.value;\r
+\r
+ //Check the process Definition key to get its test definition loaded in.\r
+ \r
+ this.checkProcessDefinitionKey();\r
+ }\r
+\r
+ //Listen for any changes made to the diagram and properties panel\r
+ this.modeler.getModel().on('element.changed', (event) => {\r
+ //check to see if process definition key has changed\r
+ if (event.element.type == 'bpmn:Process' && (this.ptd.processDefinitionKey != event.element.id)) {\r
+ this.ptd.processDefinitionKey = event.element.id;\r
+ this.checkProcessDefinitionKey();\r
+ }\r
+\r
+ // If it has been deployed, they cannot edit and save it\r
+ if (!this.ptd.currentInstance.isDeployed) {\r
+ this.ptd.currentInstance.bpmnHasChanged = true;\r
+ this.markFormAs('dirty');\r
+ }\r
+ });\r
+\r
+ this.setInProgress(false);\r
+\r
+ }\r
+\r
+ //Open a .bpmn file\r
+ async open() {\r
+\r
+ this.setInProgress(true);\r
+ this.ptd.reset();\r
+ this.ptd.switchVersion();\r
+\r
+ this.fetchFileContents('file', val => {\r
+ this.setBpmn(false, val);\r
+ });\r
+\r
+ }\r
+\r
+ //Get the xml of the default bpmn file\r
+ async getDefaultFlow() {\r
+ return new Promise((resolve, reject) => {\r
+ this._fileTransfer.get('5d0a5357e6624a3ef0d16164').subscribe(\r
+ data => {\r
+ let bpmn = new Buffer(data as Buffer);\r
+ resolve(bpmn.toString());\r
+ },\r
+ err => {\r
+ this.errorPopup(err.toString());\r
+ reject(err);\r
+ }\r
+ );\r
+ });\r
+ }\r
+\r
+ //set the Modeler\r
+ async setModeler(options) {\r
+ if (!this.modeler) {\r
+ this.modeler = await this._bpmnFactory.setup(options);\r
+ }\r
+ }\r
+\r
+ async getVersionBpmn() {\r
+ return new Promise((resolve, reject) => {\r
+ this._fileTransfer.get(this.ptd.currentInstance.bpmnFileId).subscribe(\r
+ result => {\r
+ let bpmn = new Buffer(result as Buffer);\r
+ resolve(bpmn.toString());\r
+ },\r
+ err => {\r
+ this.errorPopup(err.toString());\r
+ reject(err);\r
+ }\r
+ );\r
+ });\r
+ }\r
+\r
+ fetchFileContents(elementId, callback) {\r
+ var val = "x";\r
+ var fileToLoad = (document.getElementById(elementId))['files'][0];\r
+ var fileReader = new FileReader();\r
+ if (!fileToLoad) {\r
+ return null;\r
+ }\r
+\r
+ fileReader.onload = function (event) {\r
+ val = event.target['result'] as string;\r
+ callback(val);\r
+ }\r
+ fileReader.readAsText(fileToLoad);\r
+ }\r
+\r
+ /*****************************************\r
+ * Page Funtionality Methods\r
+ ****************************************/\r
+\r
+ toggleSidebar(set: Boolean) {\r
+ if (!set) {\r
+ this.showSidebar = false;\r
+ this.modelerElement.nativeElement.style.right = '0px';\r
+ } else {\r
+ this.showSidebar = true;\r
+ $(this.modelerElement.nativeElement).css('right', $(this.sidebarElement.nativeElement).width());\r
+ }\r
+ }\r
+\r
+ toggleProperties() {\r
+ if (!this.showProperties) {\r
+ this.toggleSidebar(true);\r
+ this.showTestDefinition = false;\r
+ this.showProperties = true;\r
+ } else {\r
+ this.toggleSidebar(false);\r
+ this.showProperties = false;\r
+ }\r
+ }\r
+\r
+ toggleTestDefinition() {\r
+ if (!this.showTestDefinition) {\r
+ this.toggleSidebar(true);\r
+ this.showProperties = false;\r
+ this.showTestDefinition = true;\r
+ } else {\r
+ this.toggleSidebar(false);\r
+ this.showTestDefinition = false;\r
+ }\r
+\r
+ this.refresh();\r
+ }\r
+\r
+ refresh() {\r
+ this.isRefreshed = false;\r
+ setTimeout(() => {\r
+ this.isRefreshed = true;\r
+ }, 1);\r
+ }\r
+\r
+ snackAlert(msg) {\r
+ this._snack.openFromComponent(AlertSnackbarComponent, {\r
+ duration: 1500,\r
+ data: {\r
+ message: msg\r
+ }\r
+ });\r
+ }\r
+\r
+ errorPopup(err) {\r
+ return this._dialog.open(AlertModalComponent, {\r
+ width: '400px',\r
+ data: {\r
+ type: 'alert',\r
+ message: err\r
+ }\r
+ });\r
+ }\r
+}\r