diff --git a/package-lock.json b/package-lock.json
index 5c10385..869742b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3522,15 +3522,6 @@
"tweetnacl": "^0.14.3"
}
},
- "better-assert": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
- "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
- "dev": true,
- "requires": {
- "callsite": "1.0.0"
- }
- },
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@@ -3959,12 +3950,6 @@
"caller-callsite": "^2.0.0"
}
},
- "callsite": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
- "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=",
- "dev": true
- },
"callsites": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
@@ -5763,64 +5748,6 @@
"once": "^1.4.0"
}
},
- "engine.io": {
- "version": "3.4.2",
- "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.2.tgz",
- "integrity": "sha512-b4Q85dFkGw+TqgytGPrGgACRUhsdKc9S9ErRAXpPGy/CXKs4tYoHDkvIRdsseAF7NjfVwjRFIn6KTnbw7LwJZg==",
- "dev": true,
- "requires": {
- "accepts": "~1.3.4",
- "base64id": "2.0.0",
- "cookie": "0.3.1",
- "debug": "~4.1.0",
- "engine.io-parser": "~2.2.0",
- "ws": "^7.1.2"
- },
- "dependencies": {
- "cookie": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
- "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
- "dev": true
- },
- "ws": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
- "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==",
- "dev": true
- }
- }
- },
- "engine.io-client": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.3.tgz",
- "integrity": "sha512-0NGY+9hioejTEJCaSJZfWZLk4FPI9dN+1H1C4+wj2iuFba47UgZbJzfWs4aNFajnX/qAaYKbe2lLTfEEWzCmcw==",
- "dev": true,
- "requires": {
- "component-emitter": "~1.3.0",
- "component-inherit": "0.0.3",
- "debug": "~4.1.0",
- "engine.io-parser": "~2.2.0",
- "has-cors": "1.1.0",
- "indexof": "0.0.1",
- "parseqs": "0.0.5",
- "parseuri": "0.0.5",
- "ws": "~6.1.0",
- "xmlhttprequest-ssl": "~1.5.4",
- "yeast": "0.1.2"
- },
- "dependencies": {
- "ws": {
- "version": "6.1.4",
- "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz",
- "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==",
- "dev": true,
- "requires": {
- "async-limiter": "~1.0.0"
- }
- }
- }
- },
"engine.io-parser": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz",
@@ -9513,12 +9440,6 @@
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
- "object-component": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
- "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=",
- "dev": true
- },
"object-copy": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
@@ -10118,24 +10039,6 @@
"integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
"optional": true
},
- "parseqs": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
- "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
- "dev": true,
- "requires": {
- "better-assert": "~1.0.0"
- }
- },
- "parseuri": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
- "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
- "dev": true,
- "requires": {
- "better-assert": "~1.0.0"
- }
- },
"parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -12674,53 +12577,69 @@
}
},
"socket.io": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz",
- "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.4.1.tgz",
+ "integrity": "sha512-Si18v0mMXGAqLqCVpTxBa8MGqriHGQh8ccEOhmsmNS3thNCGBwO8WGrwMibANsWtQQ5NStdZwHqZR3naJVFc3w==",
"dev": true,
"requires": {
"debug": "~4.1.0",
- "engine.io": "~3.4.0",
+ "engine.io": "~3.5.0",
"has-binary2": "~1.0.2",
"socket.io-adapter": "~1.1.0",
- "socket.io-client": "2.3.0",
+ "socket.io-client": "2.4.0",
"socket.io-parser": "~3.4.0"
- }
- },
- "socket.io-adapter": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz",
- "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==",
- "dev": true
- },
- "socket.io-client": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz",
- "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==",
- "dev": true,
- "requires": {
- "backo2": "1.0.2",
- "base64-arraybuffer": "0.1.5",
- "component-bind": "1.0.0",
- "component-emitter": "1.2.1",
- "debug": "~4.1.0",
- "engine.io-client": "~3.4.0",
- "has-binary2": "~1.0.2",
- "has-cors": "1.1.0",
- "indexof": "0.0.1",
- "object-component": "0.0.3",
- "parseqs": "0.0.5",
- "parseuri": "0.0.5",
- "socket.io-parser": "~3.3.0",
- "to-array": "0.1.4"
},
"dependencies": {
- "component-emitter": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
- "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "cookie": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
+ "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
"dev": true
},
+ "engine.io": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.5.0.tgz",
+ "integrity": "sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA==",
+ "dev": true,
+ "requires": {
+ "accepts": "~1.3.4",
+ "base64id": "2.0.0",
+ "cookie": "~0.4.1",
+ "debug": "~4.1.0",
+ "engine.io-parser": "~2.2.0",
+ "ws": "~7.4.2"
+ }
+ },
+ "engine.io-client": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.0.tgz",
+ "integrity": "sha512-12wPRfMrugVw/DNyJk34GQ5vIVArEcVMXWugQGGuw2XxUSztFNmJggZmv8IZlLyEdnpO1QB9LkcjeWewO2vxtA==",
+ "dev": true,
+ "requires": {
+ "component-emitter": "~1.3.0",
+ "component-inherit": "0.0.3",
+ "debug": "~3.1.0",
+ "engine.io-parser": "~2.2.0",
+ "has-cors": "1.1.0",
+ "indexof": "0.0.1",
+ "parseqs": "0.0.6",
+ "parseuri": "0.0.6",
+ "ws": "~7.4.2",
+ "xmlhttprequest-ssl": "~1.5.4",
+ "yeast": "0.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
"isarray": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
@@ -12733,15 +12652,35 @@
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
},
- "socket.io-parser": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz",
- "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==",
+ "parseqs": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz",
+ "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==",
+ "dev": true
+ },
+ "parseuri": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz",
+ "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==",
+ "dev": true
+ },
+ "socket.io-client": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.4.0.tgz",
+ "integrity": "sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ==",
"dev": true,
"requires": {
- "component-emitter": "1.2.1",
+ "backo2": "1.0.2",
+ "component-bind": "1.0.0",
+ "component-emitter": "~1.3.0",
"debug": "~3.1.0",
- "isarray": "2.0.1"
+ "engine.io-client": "~3.5.0",
+ "has-binary2": "~1.0.2",
+ "indexof": "0.0.1",
+ "parseqs": "0.0.6",
+ "parseuri": "0.0.6",
+ "socket.io-parser": "~3.3.0",
+ "to-array": "0.1.4"
},
"dependencies": {
"debug": {
@@ -12752,11 +12691,34 @@
"requires": {
"ms": "2.0.0"
}
+ },
+ "socket.io-parser": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz",
+ "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==",
+ "dev": true,
+ "requires": {
+ "component-emitter": "~1.3.0",
+ "debug": "~3.1.0",
+ "isarray": "2.0.1"
+ }
}
}
+ },
+ "ws": {
+ "version": "7.4.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz",
+ "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==",
+ "dev": true
}
}
},
+ "socket.io-adapter": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz",
+ "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==",
+ "dev": true
+ },
"socket.io-parser": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz",
diff --git a/src/app/_dialogs/confirm-dialog/confirm-dialog.component.html b/src/app/_dialogs/confirm-dialog/confirm-dialog.component.html
new file mode 100644
index 0000000..690e062
--- /dev/null
+++ b/src/app/_dialogs/confirm-dialog/confirm-dialog.component.html
@@ -0,0 +1,12 @@
+
+
+ {{data.title}}
+
+ {{data.message}}
+
+
+
+
+
+
+
diff --git a/src/app/_dialogs/confirm-dialog/confirm-dialog.component.scss b/src/app/_dialogs/confirm-dialog/confirm-dialog.component.scss
new file mode 100644
index 0000000..e9de670
--- /dev/null
+++ b/src/app/_dialogs/confirm-dialog/confirm-dialog.component.scss
@@ -0,0 +1,3 @@
+mat-dialog-container {
+ padding: 0px !important
+}
diff --git a/src/app/_dialogs/confirm-dialog/confirm-dialog.component.spec.ts b/src/app/_dialogs/confirm-dialog/confirm-dialog.component.spec.ts
new file mode 100644
index 0000000..1483f34
--- /dev/null
+++ b/src/app/_dialogs/confirm-dialog/confirm-dialog.component.spec.ts
@@ -0,0 +1,40 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
+import { ConfirmDialogComponent } from './confirm-dialog.component';
+
+
+describe('ConfirmDialogComponent', () => {
+ let component: ConfirmDialogComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ConfirmDialogComponent ],
+ imports : [MatDialogModule],
+ providers: [
+ {
+ provide: MatDialogRef,
+ useValue: {
+ close: (dialogResult: any) => {
+ }
+ }
+ },
+ {provide: MAT_DIALOG_DATA, useValue: {
+ confirm: false,
+ }},
+ ]
+
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ConfirmDialogComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/_dialogs/confirm-dialog/confirm-dialog.component.ts b/src/app/_dialogs/confirm-dialog/confirm-dialog.component.ts
new file mode 100644
index 0000000..4eb099e
--- /dev/null
+++ b/src/app/_dialogs/confirm-dialog/confirm-dialog.component.ts
@@ -0,0 +1,27 @@
+import { Component, OnInit, Inject} from '@angular/core';
+import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
+import {ConfirmDialogData} from '../../_interfaces/dialog-data';
+
+@Component({
+ selector: 'app-confirm-dialog',
+ templateUrl: './confirm-dialog.component.html',
+ styleUrls: ['./confirm-dialog.component.scss']
+})
+export class ConfirmDialogComponent {
+
+ constructor(
+ public dialogRef: MatDialogRef,
+ @Inject(MAT_DIALOG_DATA) public data: ConfirmDialogData
+ ) {
+ }
+
+ onConfirm(): void {
+ // Close the dialog, return true
+ this.dialogRef.close(true);
+ }
+
+ onDismiss(): void {
+ // Close the dialog, return false
+ this.dialogRef.close(false);
+ }
+}
diff --git a/src/app/_dialogs/delete-file-dialog/delete-file-dialog.component.ts b/src/app/_dialogs/delete-file-dialog/delete-file-dialog.component.ts
index 6313b5f..2508364 100644
--- a/src/app/_dialogs/delete-file-dialog/delete-file-dialog.component.ts
+++ b/src/app/_dialogs/delete-file-dialog/delete-file-dialog.component.ts
@@ -27,4 +27,5 @@ export class DeleteFileDialogComponent {
this.dialogRef.close(data);
}
+
}
diff --git a/src/app/_interfaces/dialog-data.ts b/src/app/_interfaces/dialog-data.ts
index 48ce9db..8eb5ffa 100644
--- a/src/app/_interfaces/dialog-data.ts
+++ b/src/app/_interfaces/dialog-data.ts
@@ -39,6 +39,13 @@ export interface DeleteFileDialogData {
fileMeta: FileMeta;
}
+export interface ConfirmDialogData {
+ title: string;
+ message: string;
+}
+
+
+
export interface DeleteWorkflowSpecDialogData {
confirm: boolean;
workflowSpec: WorkflowSpec;
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 4e9f00b..f255d93 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -51,6 +51,7 @@ import {ReferenceFilesComponent} from './reference-files/reference-files.compone
import {WorkflowSpecCardComponent} from './workflow-spec-card/workflow-spec-card.component';
import {WorkflowSpecListComponent} from './workflow-spec-list/workflow-spec-list.component';
import {MatSidenavModule} from '@angular/material/sidenav';
+import { ConfirmDialogComponent } from './_dialogs/confirm-dialog/confirm-dialog.component';
@Injectable()
export class ThisEnvironment implements AppEnvironment {
@@ -100,6 +101,7 @@ export function getBaseHref(platformLocation: PlatformLocation): string {
WorkflowSpecCardComponent,
ProtocolBuilderComponent,
ReferenceFilesComponent,
+ ConfirmDialogComponent,
],
imports: [
BrowserAnimationsModule,
diff --git a/src/app/modeler/modeler.component.html b/src/app/modeler/modeler.component.html
index 8fcbfd6..ab4c6a0 100644
--- a/src/app/modeler/modeler.component.html
+++ b/src/app/modeler/modeler.component.html
@@ -1,6 +1,6 @@
-
+
arrow_back
Back
@@ -45,14 +45,10 @@
-
-
-
-
-
-
-
-
-
-
- folder_open
-
-
-
-
-
-
- link
-
-
-
- Open file arrow_forward
-
- close
-
+
+
diff --git a/src/app/modeler/modeler.component.spec.ts b/src/app/modeler/modeler.component.spec.ts
index dafe1a9..79fe2ac 100644
--- a/src/app/modeler/modeler.component.spec.ts
+++ b/src/app/modeler/modeler.component.spec.ts
@@ -182,25 +182,6 @@ describe('ModelerComponent', () => {
expect(component.importWarnings).toEqual(warnings);
});
- it('loads a diagram from URL', () => {
- component.diagramUrl = 'some-url';
- component.openMethod = 'url';
- component.onSubmitFileToOpen();
-
- const sReq = httpMock.expectOne(component.diagramUrl);
- expect(sReq.request.method).toEqual('GET');
- sReq.flush(BPMN_DIAGRAM);
- });
-
- it('loads a diagram from URL with warnings', () => {
- component.diagramUrl = 'some-url';
- component.openMethod = 'url';
- component.onSubmitFileToOpen();
-
- const sReq = httpMock.expectOne(component.diagramUrl);
- expect(sReq.request.method).toEqual('GET');
- sReq.flush(BPMN_DIAGRAM_WITH_WARNINGS);
- });
it('loads a diagram from File', () => {
const readFileSpy = spyOn(component, 'readFile').and.stub();
@@ -499,12 +480,13 @@ describe('ModelerComponent', () => {
const data: OpenFileDialogData = {
file: mockFileMeta0.file
};
+ const expectedFile = new File([], mockFileMeta0.name, {type: mockFileMeta0.content_type});
+ const event = {target: {files: [expectedFile]}};
const onSubmitFileToOpenSpy = spyOn(component, 'onSubmitFileToOpen').and.stub();
- const openDialogSpy = spyOn(component.dialog, 'open')
- .and.returnValue({afterClosed: () => of(data)});
component.openFileDialog();
- expect(openDialogSpy).toHaveBeenCalled();
+ expect(component.requestFileClick).toBeTrue();
+ component.onFileSelected(event);
expect(component.diagramFile).toEqual(data.file);
expect(onSubmitFileToOpenSpy).toHaveBeenCalled();
});
diff --git a/src/app/modeler/modeler.component.ts b/src/app/modeler/modeler.component.ts
index d86e18b..1469d11 100644
--- a/src/app/modeler/modeler.component.ts
+++ b/src/app/modeler/modeler.component.ts
@@ -1,9 +1,10 @@
import {DatePipe} from '@angular/common';
-import {AfterViewInit, Component, ViewChild} from '@angular/core';
+import {AfterViewInit, Component, ElementRef, ViewChild} from '@angular/core';
import {MatBottomSheet} from '@angular/material/bottom-sheet';
import {MatDialog} from '@angular/material/dialog';
import {MatSnackBar} from '@angular/material/snack-bar';
import {ActivatedRoute, Params, Router} from '@angular/router';
+
import {
ApiErrorsComponent,
ApiService,
@@ -16,9 +17,9 @@ import {
} from 'sartography-workflow-lib';
import {FileMetaDialogComponent} from '../_dialogs/file-meta-dialog/file-meta-dialog.component';
import {NewFileDialogComponent} from '../_dialogs/new-file-dialog/new-file-dialog.component';
-import {OpenFileDialogComponent} from '../_dialogs/open-file-dialog/open-file-dialog.component';
+import {ConfirmDialogComponent} from '../_dialogs/confirm-dialog/confirm-dialog.component';
import {BpmnWarning} from '../_interfaces/bpmn-warning';
-import {FileMetaDialogData, NewFileDialogData, OpenFileDialogData} from '../_interfaces/dialog-data';
+import {FileMetaDialogData, NewFileDialogData} from '../_interfaces/dialog-data';
import {ImportEvent} from '../_interfaces/import-event';
import {DiagramComponent} from '../diagram/diagram.component';
@@ -28,25 +29,6 @@ import {DiagramComponent} from '../diagram/diagram.component';
styleUrls: ['./modeler.component.scss']
})
export class ModelerComponent implements AfterViewInit {
- title = 'bpmn-js-angular';
- diagramUrl = 'https://cdn.staticaly.com/gh/bpmn-io/bpmn-js-examples/dfceecba/starter/diagram.bpmn';
- importError?: Error;
- importWarnings?: BpmnWarning[];
- expandToolbar = false;
- openMethod: string;
- diagramFile: File;
- workflowSpec: WorkflowSpec;
- bpmnFiles: FileMeta[] = [];
- diagramFileMeta: FileMeta;
- fileName: string;
- fileTypes = FileType;
- private xml = '';
- private draftXml = '';
- private svg = '';
- @ViewChild(DiagramComponent) private diagramComponent: DiagramComponent;
- private diagramType: FileType;
- private workflowSpecId: string;
- private fileMetaId: number;
constructor(
private api: ApiService,
@@ -66,13 +48,51 @@ export class ModelerComponent implements AfterViewInit {
this.loadFilesFromDb();
});
}
+ title = 'bpmn-js-angular';
+ diagramUrl = 'https://cdn.staticaly.com/gh/bpmn-io/bpmn-js-examples/dfceecba/starter/diagram.bpmn';
+ importError?: Error;
+ importWarnings?: BpmnWarning[];
+ expandToolbar = false;
+ openMethod: string;
+ diagramFile: File;
+ workflowSpec: WorkflowSpec;
+ bpmnFiles: FileMeta[] = [];
+ diagramFileMeta: FileMeta;
+ fileName: string;
+ fileTypes = FileType;
+ private xml = '';
+ private draftXml = '';
+ private svg = '';
+ @ViewChild(DiagramComponent) private diagramComponent: DiagramComponent;
+ @ViewChild('fileInput', {static: true}) fileInput: ElementRef;
+ private diagramType: FileType;
+ private workflowSpecId: string;
+ private fileMetaId: number;
+ private isNew = false;
+ private requestFileClick = false;
+
+ static isXmlFile(file: File) {
+ return file.type.toLowerCase() === 'text/xml' ||
+ file.type.toLowerCase() === 'application/xml' ||
+ file.name.slice(-5).toLowerCase() === '.bpmn' ||
+ file.name.slice(-4).toLowerCase() === '.dmn' ||
+ file.name.slice(-4).toLowerCase() === '.xml';
+ }
ngAfterViewInit(): void {
this.diagramComponent.registerOnChange((newXmlValue: string, newSvgValue: string) => {
console.log('ModelerComponent > DiagramComponent > onChange');
- this.draftXml = newXmlValue;
+ if (this.draftXml !== newXmlValue + ' ') {
+ // When we initialize a new dmn, the component registers a change even if nothing
+ // changes. So . . . we check to make sure it *really* changed before updating the draftXml.
+ this.draftXml = newXmlValue;
+ }
this.svg = newSvgValue;
});
+ if (this.requestFileClick) {
+ this.fileInput.nativeElement.click();
+ this.requestFileClick = false;
+ }
}
handleImported(event: ImportEvent) {
@@ -92,23 +112,27 @@ export class ModelerComponent implements AfterViewInit {
this.importError = error;
this.importWarnings = warnings;
- this.draftXml = this.xml + ' ';
+
+ // if this is a new file then we force a change to the file
+ if (this.isNew ) {
+ this.draftXml = this.xml + ' ';
+ this.isNew = false;
+ } else {
+ this.draftXml = this.xml;
+ }
}
onSubmitFileToOpen() {
this.expandToolbar = false;
- if (this.openMethod === 'url') {
- this.diagramComponent.loadUrl(this.diagramUrl);
+
+ if (this.diagramFile && ModelerComponent.isXmlFile(this.diagramFile)) {
+ this.readFile(this.diagramFile);
} else {
- if (this.diagramFile && this.isXmlFile(this.diagramFile)) {
- this.readFile(this.diagramFile);
- } else {
- this.handleImported({
- type: 'error',
- error: new Error('Wrong file type. Please choose a BPMN XML file.')
- });
- }
+ this.handleImported({
+ type: 'error',
+ error: new Error('Wrong file type. Please choose a BPMN XML file.')
+ });
}
this.openMethod = undefined;
@@ -118,8 +142,28 @@ export class ModelerComponent implements AfterViewInit {
return this.diagramFile ? this.diagramFile.name : this.fileName || 'No file selected';
}
+ checkSaved() {
+ if (this.hasChanged()) {
+ const dialogRef = this.dialog.open(ConfirmDialogComponent, {
+ maxWidth: '300px',
+ data: {
+ title: 'Unsaved Changes!',
+ message : 'Are you sure you want to abandon changes?',
+ }
+ });
+ dialogRef.afterClosed().subscribe(dialogResult => {
+ if (dialogResult) {
+ this.router.navigate(['/home', this.workflowSpec.name]);
+ }});
+ } else {
+ this.router.navigate(['/home', this.workflowSpec.name]);
+ }
+ }
+
onFileSelected($event: Event) {
this.diagramFile = ($event.target as HTMLFormElement).files[0];
+ this.onSubmitFileToOpen();
+ this.isNew = true;
}
// Arrow function here preserves this context
@@ -159,7 +203,7 @@ export class ModelerComponent implements AfterViewInit {
}
hasChanged(): boolean {
- return this.xml !== this.draftXml;
+ return (this.xml !== this.draftXml) || this.isNew;
}
loadDbFile(bf: FileMeta) {
@@ -180,18 +224,14 @@ export class ModelerComponent implements AfterViewInit {
}
openFileDialog() {
- const dialogData: OpenFileDialogData = {
- file: undefined,
- fileTypes: [FileType.DMN, FileType.BPMN],
- };
- const dialogRef = this.dialog.open(OpenFileDialogComponent, {data: dialogData});
+ // NB - Aaron said that doing this may be problematic.
+ // When we are handling the action in the constructor, the component hasn't been
+ // Rendered yet. I needed to call fileInput.click() after the component has rendered.
- dialogRef.afterClosed().subscribe((data: OpenFileDialogData) => {
- if (data && data.file) {
- this.diagramFile = data.file;
- this.onSubmitFileToOpen();
- }
- });
+ // In order to make this work, I check for the requestFileClick variable in ngAfterViewInit
+ // and then click it. I couldn't see any other way to make this do what I wanted to do
+ // it *appears* to work fine.
+ this.requestFileClick = true;
}
newFileDialog() {
@@ -303,27 +343,25 @@ export class ModelerComponent implements AfterViewInit {
this.api.addFileMeta({workflow_spec_id: this.workflowSpec.id}, this.diagramFileMeta).subscribe(fileMeta => {
this.router.navigate(['/modeler', this.workflowSpec.id, fileMeta.id]);
this.snackBar.open(`Saved new file ${fileMeta.name} to workflow spec ${this.workflowSpec.name}.`, 'Ok', {duration: 5000});
+ }, () => {
+ // if this fails, we make sure that the file is treated as still new,
+ // and we make the user re-enter the file details as they weren't actually saved.
+ this.isNew = true;
+ this.diagramFileMeta = undefined;
});
}
}
}
- private isXmlFile(file: File) {
- return file.type.toLowerCase() === 'text/xml' ||
- file.type.toLowerCase() === 'application/xml' ||
- file.name.slice(-5).toLowerCase() === '.bpmn' ||
- file.name.slice(-4).toLowerCase() === '.dmn' ||
- file.name.slice(-4).toLowerCase() === '.xml';
- }
-
private saveFileChanges() {
this.xml = this.draftXml;
this.diagramFileMeta.file = new File([this.xml], this.diagramFileMeta.name, {type: 'text/xml'});
- if (this.svg && this.svg !== '') {
- const svgFile = new File([this.svg], this.diagramFileMeta.name, {type: 'text/xml'});
- // this.api.updateFileData();
- }
+ // Propose removal
+ // if (this.svg && this.svg !== '') {
+ // const svgFile = new File([this.svg], this.diagramFileMeta.name, {type: 'text/xml'});
+ // // this.api.updateFileData();
+ // }
this.api.updateFileData(this.diagramFileMeta).subscribe(newFileMeta => {
this.diagramFileMeta = newFileMeta;
@@ -340,4 +378,5 @@ export class ModelerComponent implements AfterViewInit {
}
}
}
+
}