Consolidates dialogs into a single directory. Displays confirmation dialog before deleting a file.

This commit is contained in:
Aaron Louie 2020-01-29 11:15:58 -05:00
parent c4fde9e438
commit 1ad1c4e3cc
28 changed files with 153 additions and 32 deletions

View File

@ -0,0 +1,16 @@
<div mat-dialog-title>
Delete file <strong>{{data.fileMeta.name}}</strong>?
<button mat-icon-button mat-dialog-close=""><mat-icon>close</mat-icon></button>
</div>
<div mat-dialog-content>
<div class="select-mode" fxLayoutAlign="center center" fxLayout="row" fxLayoutGap="20px">
<button (click)="onSubmit()" color="warn" mat-flat-button>
<mat-icon>check</mat-icon>
Yes
</button>
<button (click)="onNoClick()" color="primary" mat-flat-button>
<mat-icon>close</mat-icon>
No
</button>
</div>
</div>

View File

@ -0,0 +1,9 @@
.select-mode {
width: 100%;
height: 100%;
::ng-deep button {
padding: 1em 2em;
margin: 1em;
}
}

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DeleteFileDialogComponent } from './delete-file-dialog.component';
describe('DeleteFileDialogComponent', () => {
let component: DeleteFileDialogComponent;
let fixture: ComponentFixture<DeleteFileDialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DeleteFileDialogComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DeleteFileDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,30 @@
import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
import {DeleteFileDialogData} from '../../_interfaces/dialog-data';
@Component({
selector: 'app-delete-file-dialog',
templateUrl: './delete-file-dialog.component.html',
styleUrls: ['./delete-file-dialog.component.scss']
})
export class DeleteFileDialogComponent {
constructor(
public dialogRef: MatDialogRef<DeleteFileDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: DeleteFileDialogData
) {
}
onNoClick() {
this.dialogRef.close();
}
onSubmit() {
const data: DeleteFileDialogData = {
confirm: true,
fileMeta: this.data.fileMeta,
};
this.dialogRef.close(data);
}
}

View File

@ -5,7 +5,7 @@ import {MatFormFieldModule} from '@angular/material/form-field';
import {MatInputModule} from '@angular/material/input';
import {BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations';
import {FileType} from 'sartography-workflow-lib';
import {FileMetaDialogData} from '../_interfaces/dialog-data';
import {FileMetaDialogData} from '../../_interfaces/dialog-data';
import {FileMetaDialogComponent} from './file-meta-dialog.component';
describe('EditFileMetaDialogComponent', () => {

View File

@ -1,7 +1,7 @@
import {Component, Inject} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
import {FileMetaDialogData} from '../_interfaces/dialog-data';
import {cleanUpFilename} from '../_util/string-clean';
import {FileMetaDialogData} from '../../_interfaces/dialog-data';
import {cleanUpFilename} from '../../_util/string-clean';
@Component({
selector: 'app-new-file-dialog',

View File

@ -1,4 +1,6 @@
<div mat-dialog-title>
Select diagram type
<span fxFlex></span>
<button mat-icon-button mat-dialog-close=""><mat-icon>close</mat-icon></button>
</div>
<div mat-dialog-content>

View File

@ -1,7 +1,7 @@
import {Component} from '@angular/core';
import {MatDialogRef} from '@angular/material/dialog';
import {FileType} from 'sartography-workflow-lib';
import {NewFileDialogData} from '../_interfaces/dialog-data';
import {NewFileDialogData} from '../../_interfaces/dialog-data';
@Component({
selector: 'app-new-file-dialog',

View File

@ -1,3 +1,10 @@
<div mat-dialog-title>
<ng-container *ngIf="!mode">Where is your file?</ng-container>
<ng-container *ngIf="mode === 'local'">Upload a local BPMN/DMN file</ng-container>
<ng-container *ngIf="mode === 'remote'">Open a BPMN/DMN file from URL</ng-container>
<span fxFlex></span>
<button mat-icon-button mat-dialog-close=""><mat-icon>close</mat-icon></button>
</div>
<div mat-dialog-content>
<div *ngIf="!mode" class="select-mode" fxLayoutAlign="center center">
<button (click)="mode = 'local'" color="primary" mat-flat-button>
@ -11,9 +18,8 @@
</div>
<div *ngIf="mode === 'local'">
<h1>Upload a local file</h1>
<mat-form-field (click)="fileInput.click()">
<mat-icon matPrefix>folder_open</mat-icon>
<span matPrefix><mat-icon>folder_open</mat-icon> &nbsp;</span>
<input [value]="getFileName()" disabled matInput type="text">
</mat-form-field>
<input #fileInput (change)="onFileSelected($event)" accept=".bpmn,.dmn,.xml,application/xml,text/xml" hidden id="file"
@ -23,9 +29,9 @@
</div>
<div *ngIf="mode === 'remote'">
<h1>Open a file from a URL</h1>
<mat-form-field>
<input [(ngModel)]="url" matInput placeholder="BPMN/DMN File URL" type="url">
<span matPrefix><mat-icon>link</mat-icon> &nbsp;</span>
<input [(ngModel)]="url" matInput type="url" placeholder="BPMN/DMN File URL">
</mat-form-field>
<button (click)="onSubmitUrl()" [disabled]="!isValidUrl()" color="primary" mat-flat-button>Fetch File</button>
<button (click)="mode = undefined" mat-flat-button>Cancel</button>

View File

@ -1,8 +1,8 @@
import { Component, OnInit } from '@angular/core';
import {MatDialogRef} from '@angular/material/dialog';
import {ApiService} from 'sartography-workflow-lib';
import {getDiagramTypeFromXml} from '../_util/diagram-type';
import {cleanUpFilename} from '../_util/string-clean';
import {getDiagramTypeFromXml} from '../../_util/diagram-type';
import {cleanUpFilename} from '../../_util/string-clean';
@Component({
selector: 'app-open-file-dialog',
@ -33,7 +33,7 @@ export class OpenFileDialogComponent {
}
getFileName() {
return this.diagramFile ? this.diagramFile.name : 'No file selected';
return this.diagramFile ? this.diagramFile.name : 'Click to select a file';
}
onSubmitUrl() {

View File

@ -3,8 +3,8 @@ import {FormGroup} from '@angular/forms';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
import {FormlyFieldConfig, FormlyFormOptions} from '@ngx-formly/core';
import {v4 as uuidv4} from 'uuid';
import {WorkflowSpecDialogData} from '../_interfaces/dialog-data';
import {toSnakeCase} from '../_util/string-clean';
import {WorkflowSpecDialogData} from '../../_interfaces/dialog-data';
import {toSnakeCase} from '../../_util/string-clean';
@Component({
selector: 'app-workflow-spec-dialog',

View File

@ -1,4 +1,4 @@
import {FileType} from 'sartography-workflow-lib';
import {FileMeta, FileType} from 'sartography-workflow-lib';
export interface FileMetaDialogData {
fileName: string;
@ -19,3 +19,8 @@ export interface WorkflowSpecDialogData {
display_name: string;
description: string;
}
export interface DeleteFileDialogData {
confirm: boolean;
fileMeta: FileMeta;
}

View File

@ -24,13 +24,14 @@ import {AppRoutingModule} from './app-routing.module';
import {AppComponent} from './app.component';
import {DiagramComponent} from './diagram/diagram.component';
import {FileListComponent} from './file-list/file-list.component';
import {FileMetaDialogComponent} from './file-meta-dialog/file-meta-dialog.component';
import {FileMetaDialogComponent} from './_dialogs/file-meta-dialog/file-meta-dialog.component';
import {ModelerComponent} from './modeler/modeler.component';
import {WorkflowSpecDialogComponent} from './workflow-spec-dialog/workflow-spec-dialog.component';
import {WorkflowSpecDialogComponent} from './_dialogs/workflow-spec-dialog/workflow-spec-dialog.component';
import {WorkflowSpecListComponent} from './workflow-spec-list/workflow-spec-list.component';
import { GetIconCodePipe } from './_pipes/get-icon-code.pipe';
import { NewFileDialogComponent } from './new-file-dialog/new-file-dialog.component';
import { OpenFileDialogComponent } from './open-file-dialog/open-file-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 { DeleteFileDialogComponent } from './_dialogs/delete-file-dialog/delete-file-dialog.component';
export class ThisEnvironment implements AppEnvironment {
production = environment.production;
@ -51,6 +52,7 @@ export class ThisEnvironment implements AppEnvironment {
GetIconCodePipe,
NewFileDialogComponent,
OpenFileDialogComponent,
DeleteFileDialogComponent,
],
imports: [
BrowserAnimationsModule,
@ -81,6 +83,7 @@ export class ThisEnvironment implements AppEnvironment {
],
bootstrap: [AppComponent],
entryComponents: [
DeleteFileDialogComponent,
FileMetaDialogComponent,
NewFileDialogComponent,
OpenFileDialogComponent,

View File

@ -1,9 +1,9 @@
<mat-list>
<mat-list-item *ngFor="let fm of fileMetas" (click)="editFile(fm.id)">
<mat-icon mat-list-icon>{{fm.type | getIconCode}}</mat-icon>
<h4 mat-line>{{fm.name}}</h4>
<p mat-line>{{fm.last_updated | date}}</p>
<mat-list-item *ngFor="let fm of fileMetas">
<mat-icon mat-list-icon (click)="editFile(fm.id)">{{fm.type | getIconCode}}</mat-icon>
<h4 mat-line (click)="editFile(fm.id)">{{fm.name}}</h4>
<p mat-line (click)="editFile(fm.id)">{{fm.last_updated | date}}</p>
<button mat-icon-button color="primary" (click)="editFile(fm.id)" class="mat-elevation-z0"><mat-icon>edit</mat-icon></button>
<button mat-icon-button color="warn" (click)="deleteFile(fm.id)" class="mat-elevation-z0"><mat-icon>delete</mat-icon></button>
<button mat-icon-button color="warn" (click)="confirmDelete(fm)" class="mat-elevation-z0"><mat-icon>delete</mat-icon></button>
</mat-list-item>
</mat-list>

View File

@ -1,6 +1,10 @@
import {Component, Input, OnInit} from '@angular/core';
import {MatDialog} from '@angular/material/dialog';
import {MatSnackBar} from '@angular/material/snack-bar';
import {Router} from '@angular/router';
import {ApiService, FileMeta, FileType, WorkflowSpec} from 'sartography-workflow-lib';
import {DeleteFileDialogData} from '../_interfaces/dialog-data';
import {DeleteFileDialogComponent} from '../_dialogs/delete-file-dialog/delete-file-dialog.component';
@Component({
selector: 'app-file-list',
@ -13,7 +17,9 @@ export class FileListComponent implements OnInit {
constructor(
private api: ApiService,
private router: Router
public dialog: MatDialog,
private router: Router,
private snackBar: MatSnackBar,
) {
}
@ -21,8 +27,11 @@ export class FileListComponent implements OnInit {
this.loadFileMetas();
}
deleteFile(fileMetaId: number) {
this.api.deleteFileMeta(fileMetaId).subscribe(() => this.loadFileMetas());
deleteFile(fileMeta: FileMeta) {
this.api.deleteFileMeta(fileMeta.id).subscribe(() => {
this.loadFileMetas();
this.snackBar.open(`Deleted file ${fileMeta.name}.`, 'Ok', {duration: 3000});
});
}
private loadFileMetas() {
@ -32,4 +41,19 @@ export class FileListComponent implements OnInit {
editFile(fileMetaId: number) {
this.router.navigate([`/modeler/${this.workflowSpec.id}/${fileMetaId}`]);
}
confirmDelete(fm: FileMeta) {
const dialogRef = this.dialog.open(DeleteFileDialogComponent, {
data: {
confirm: false,
fileMeta: fm,
}
});
dialogRef.afterClosed().subscribe((data: DeleteFileDialogData) => {
if (data && data.confirm && data.fileMeta) {
this.deleteFile(data.fileMeta);
}
});
}
}

View File

@ -80,13 +80,14 @@
<ng-container *ngIf="openMethod === 'file'">
<mat-form-field (click)="fileInput.click()">
<mat-icon matPrefix>folder_open</mat-icon>
<span matPrefix><mat-icon>folder_open</mat-icon> &nbsp;</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> &nbsp;</span>
<input name="diagramUrl" [(ngModel)]="diagramUrl" matInput placeholder="Open diagram from URL" type="text">
</mat-form-field>
</ng-container>

View File

@ -31,7 +31,7 @@ import {BpmnWarning} from '../_interfaces/bpmn-warning';
import {FileMetaDialogData} from '../_interfaces/dialog-data';
import {GetIconCodePipe} from '../_pipes/get-icon-code.pipe';
import {DiagramComponent} from '../diagram/diagram.component';
import {FileMetaDialogComponent} from '../file-meta-dialog/file-meta-dialog.component';
import {FileMetaDialogComponent} from '../_dialogs/file-meta-dialog/file-meta-dialog.component';
import {ModelerComponent} from './modeler.component';

View File

@ -9,9 +9,9 @@ import {FileMetaDialogData, NewFileDialogData, OpenFileDialogData} from '../_int
import {ImportEvent} from '../_interfaces/import-event';
import {getDiagramTypeFromXml} from '../_util/diagram-type';
import {DiagramComponent} from '../diagram/diagram.component';
import {FileMetaDialogComponent} from '../file-meta-dialog/file-meta-dialog.component';
import {NewFileDialogComponent} from '../new-file-dialog/new-file-dialog.component';
import {OpenFileDialogComponent} from '../open-file-dialog/open-file-dialog.component';
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';
@Component({
selector: 'app-modeler',

View File

@ -3,7 +3,7 @@ import {MatDialog} from '@angular/material/dialog';
import {MatSnackBar} from '@angular/material/snack-bar';
import {ApiService, WorkflowSpec} from 'sartography-workflow-lib';
import {WorkflowSpecDialogData} from '../_interfaces/dialog-data';
import {WorkflowSpecDialogComponent} from '../workflow-spec-dialog/workflow-spec-dialog.component';
import {WorkflowSpecDialogComponent} from '../_dialogs/workflow-spec-dialog/workflow-spec-dialog.component';
@Component({
selector: 'app-workflow-spec-list',