Merge branch 'dev' of github.com:sartography/cr-connect-bpmn into dev
This commit is contained in:
commit
77031ffe82
|
@ -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",
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<mat-card fxLayoutGap>
|
||||
|
||||
<p mat-dialog-title>{{data.title}}</p>
|
||||
|
||||
<p display-2>{{data.message}}</p>
|
||||
|
||||
|
||||
<div mat-dialog-actions>
|
||||
<button mat-button (click)="onDismiss()">No</button>
|
||||
<button mat-raised-button color="primary" (click)="onConfirm()">Yes</button>
|
||||
</div>
|
||||
</mat-card>
|
|
@ -0,0 +1,3 @@
|
|||
mat-dialog-container {
|
||||
padding: 0px !important
|
||||
}
|
|
@ -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<ConfirmDialogComponent>;
|
||||
|
||||
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();
|
||||
});
|
||||
});
|
|
@ -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<ConfirmDialogComponent>,
|
||||
@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);
|
||||
}
|
||||
}
|
|
@ -27,4 +27,5 @@ export class DeleteFileDialogComponent {
|
|||
this.dialogRef.close(data);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,13 @@ export interface DeleteFileDialogData {
|
|||
fileMeta: FileMeta;
|
||||
}
|
||||
|
||||
export interface ConfirmDialogData {
|
||||
title: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface DeleteWorkflowSpecDialogData {
|
||||
confirm: boolean;
|
||||
workflowSpec: WorkflowSpec;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<mat-toolbar [ngClass]="{'expanded': expandToolbar}">
|
||||
<mat-toolbar-row *ngIf="workflowSpec">
|
||||
<a mat-button [routerLink]="['/home', workflowSpec.name]">
|
||||
<a mat-button (click)="checkSaved()">
|
||||
<mat-icon>arrow_back</mat-icon>
|
||||
Back
|
||||
</a>
|
||||
|
@ -45,14 +45,10 @@
|
|||
</a>
|
||||
</mat-menu>
|
||||
|
||||
<button mat-menu-item (click)="openMethod = 'file'; expandToolbar = true">
|
||||
<button mat-menu-item (click)="fileInput.click()">
|
||||
<mat-icon>code</mat-icon>
|
||||
Open from XML File
|
||||
</button>
|
||||
<button mat-menu-item (click)="openMethod = 'url'; expandToolbar = true">
|
||||
<mat-icon>link</mat-icon>
|
||||
Open from URL
|
||||
</button>
|
||||
</mat-menu>
|
||||
|
||||
<button mat-button (click)="saveChanges()" [disabled]="!hasChanged()"><mat-icon>save</mat-icon></button>
|
||||
|
@ -73,37 +69,8 @@
|
|||
{{getFileName()}}
|
||||
</button>
|
||||
</mat-toolbar-row>
|
||||
<mat-toolbar-row *ngIf="expandToolbar">
|
||||
<ng-container *ngIf="!openMethod">
|
||||
<mat-form-field>
|
||||
<input matInput [(ngModel)]="fileName" placeholder="File name" type="text">
|
||||
</mat-form-field>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="openMethod === 'file'">
|
||||
<mat-form-field (click)="fileInput.click()">
|
||||
<span matPrefix><mat-icon>folder_open</mat-icon> </span>
|
||||
<input matInput disabled [value]="getFileName()" type="text">
|
||||
</mat-form-field>
|
||||
<input hidden (change)="onFileSelected($event)" #fileInput type="file" id="file" accept=".bpmn,.dmn,.xml,application/xml,text/xml">
|
||||
</ng-container>
|
||||
<ng-container *ngIf="openMethod === 'url'">
|
||||
<mat-form-field>
|
||||
<span matPrefix><mat-icon>link</mat-icon> </span>
|
||||
<input name="diagramUrl" [(ngModel)]="diagramUrl" matInput placeholder="Open diagram from URL" type="text">
|
||||
</mat-form-field>
|
||||
</ng-container>
|
||||
<button
|
||||
mat-flat-button
|
||||
(click)="onSubmitFileToOpen()"
|
||||
[disabled]="!diagramFile"
|
||||
color="primary"
|
||||
id="open_file_button"
|
||||
>Open file <mat-icon>arrow_forward</mat-icon></button>
|
||||
<span fxFlex></span>
|
||||
<button mat-icon-button (click)="expandToolbar = false"><mat-icon>close</mat-icon></button>
|
||||
</mat-toolbar-row>
|
||||
</mat-toolbar>
|
||||
|
||||
<div fxLayout="column">
|
||||
<div class="diagram-parent">
|
||||
<app-diagram #diagram (importDone)="handleImported($event)" [fileName]="getFileName()"></app-diagram>
|
||||
|
@ -115,3 +82,4 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<input hidden (change)="onFileSelected($event)" #fileInput type="file" id="file" accept=".bpmn,.dmn,.xml,application/xml,text/xml">
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue