Modified the home page of the modeler to show a menu on the left hand side that allows navigation between workflow specifications. Back button from the editor takes you back to the home page with the correct spec selected for quicker editing.
This commit is contained in:
parent
55a3308334
commit
28ddf68f68
|
@ -12077,9 +12077,9 @@
|
|||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"sartography-workflow-lib": {
|
||||
"version": "0.0.386",
|
||||
"resolved": "https://registry.npmjs.org/sartography-workflow-lib/-/sartography-workflow-lib-0.0.386.tgz",
|
||||
"integrity": "sha512-4BwaVso9miYZSIxEuWqI8lXBnCz0R42QEvahyNMkNmT7Rn2rrknYchedfipxzOMoJpo3T+5hElbDMlilgwQgWQ=="
|
||||
"version": "0.0.387",
|
||||
"resolved": "https://registry.npmjs.org/sartography-workflow-lib/-/sartography-workflow-lib-0.0.387.tgz",
|
||||
"integrity": "sha512-uVDKA++5JFEdWXaqwlVwxIK51LXpjD7vXpjS+F0SASuEYZNOzfFv8GdRvddu0kGBNaAQ+jqBFxCCbDnQxLbqfA=="
|
||||
},
|
||||
"sass": {
|
||||
"version": "1.26.3",
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
"ngx-highlightjs": "^4.1.1",
|
||||
"ngx-markdown": "^9.1.1",
|
||||
"rxjs": "~6.5.4",
|
||||
"sartography-workflow-lib": "0.0.386",
|
||||
"sartography-workflow-lib": "0.0.387",
|
||||
"tslib": "^1.13.0",
|
||||
"uuid": "^7.0.2",
|
||||
"zone.js": "^0.10.3"
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import {APP_BASE_HREF} from '@angular/common';
|
||||
import {Injectable, NgModule} from '@angular/core';
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
import {ExtraOptions, RouterModule, Routes} from '@angular/router';
|
||||
import {AppEnvironment, SessionRedirectComponent} from 'sartography-workflow-lib';
|
||||
import {environment} from '../environments/environment.runtime';
|
||||
import {HomeComponent} from './home/home.component';
|
||||
import {ModelerComponent} from './modeler/modeler.component';
|
||||
import {ProtocolBuilderComponent} from './protocol-builder/protocol-builder.component';
|
||||
import {ReferenceFilesComponent} from './reference-files/reference-files.component';
|
||||
import {WorkflowSpecListComponent} from './workflow-spec-list/workflow-spec-list.component';
|
||||
|
||||
@Injectable()
|
||||
export class ThisEnvironment implements AppEnvironment {
|
||||
|
@ -29,6 +30,10 @@ const routes: Routes = [
|
|||
path: 'home',
|
||||
component: HomeComponent
|
||||
},
|
||||
{
|
||||
path: 'home/:spec',
|
||||
component: WorkflowSpecListComponent
|
||||
},
|
||||
{
|
||||
path: 'pb',
|
||||
component: ProtocolBuilderComponent
|
||||
|
|
|
@ -50,6 +50,7 @@ import {ProtocolBuilderComponent} from './protocol-builder/protocol-builder.comp
|
|||
import {ReferenceFilesComponent} from './reference-files/reference-files.component';
|
||||
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';
|
||||
|
||||
@Injectable()
|
||||
export class ThisEnvironment implements AppEnvironment {
|
||||
|
@ -124,7 +125,9 @@ export function getBaseHref(platformLocation: PlatformLocation): string {
|
|||
SartographyFormsModule,
|
||||
SartographyPipesModule,
|
||||
SartographyWorkflowLibModule,
|
||||
AppRoutingModule, // <-- This line MUST be last (https://angular.io/guide/router#module-import-order-matters)
|
||||
AppRoutingModule,
|
||||
MatSidenavModule,
|
||||
// <-- This line MUST be last (https://angular.io/guide/router#module-import-order-matters)
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
entryComponents: [
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {Component, Input, OnChanges, OnInit} from '@angular/core';
|
||||
import {MatDialog} from '@angular/material/dialog';
|
||||
import {MatSnackBar} from '@angular/material/snack-bar';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
|
@ -21,7 +21,7 @@ import * as fileSaver from 'file-saver';
|
|||
templateUrl: './file-list.component.html',
|
||||
styleUrls: ['./file-list.component.scss']
|
||||
})
|
||||
export class FileListComponent implements OnInit {
|
||||
export class FileListComponent implements OnInit, OnChanges {
|
||||
@Input() workflowSpec: WorkflowSpec;
|
||||
fileMetas: FileMeta[];
|
||||
fileType = FileType;
|
||||
|
@ -39,6 +39,10 @@ export class FileListComponent implements OnInit {
|
|||
this._loadFileMetas();
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
this._loadFileMetas();
|
||||
}
|
||||
|
||||
editFile(fileMeta?: FileMeta) {
|
||||
if (fileMeta && ((fileMeta.type === FileType.BPMN) || (fileMeta.type === FileType.DMN))) {
|
||||
this.router.navigate([`/modeler/${this.workflowSpec.id}/${fileMeta.id}`]);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<mat-toolbar [ngClass]="{'expanded': expandToolbar}">
|
||||
<mat-toolbar-row *ngIf="workflowSpec">
|
||||
<a mat-button [routerLink]="['/']">
|
||||
<a mat-button [routerLink]="['/home', workflowSpec.name]">
|
||||
<mat-icon>arrow_back</mat-icon>
|
||||
Back
|
||||
</a>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
<div class="container mat-typography" fxLayout="column" fxLayoutGap="10px">
|
||||
<h1>Workflow Specifications</h1>
|
||||
<div fxLayout="row" fxLayoutGap="10px">
|
||||
|
@ -11,86 +10,114 @@
|
|||
Add category
|
||||
</button>
|
||||
</div>
|
||||
<ng-container *ngFor="let cat of workflowSpecsByCategory">
|
||||
<ng-container *ngIf="!(cat.id === null && cat.workflow_specs.length === 0)">
|
||||
<div class="category" fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="start center">
|
||||
<h2>{{cat.display_name}} ({{cat.name}})</h2>
|
||||
<div class="category-actions" fxLayout="row" fxLayoutGap="10px" *ngIf="cat.id !== null">
|
||||
<button mat-mini-fab color="primary" (click)="editWorkflowSpecCategory(cat)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="cat.display_order > 0"
|
||||
mat-mini-fab
|
||||
title="Move up"
|
||||
color="primary"
|
||||
(click)="editCategoryDisplayOrder(cat.id, -1, workflowSpecsByCategory)"
|
||||
>
|
||||
<mat-icon>arrow_upward</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="cat.display_order < workflowSpecsByCategory.length - 2"
|
||||
mat-mini-fab
|
||||
title="Move down"
|
||||
color="primary"
|
||||
(click)="editCategoryDisplayOrder(cat.id, 1, workflowSpecsByCategory)"
|
||||
>
|
||||
<mat-icon>arrow_downward</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button title="Delete this category" color="warn" (click)="confirmDeleteWorkflowSpecCategory(cat)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
<mat-drawer-container class="example-container" autosize>
|
||||
<mat-drawer #drawer class="example-sidenav" mode="side" opened="true">
|
||||
<ng-container *ngIf="masterStatusSpec">
|
||||
<div class="category">
|
||||
<h4>Master Specification</h4>
|
||||
<mat-list>
|
||||
<mat-list-item class="workflow-spec" fxLayout="row">
|
||||
<a class="spec_menu_item" (click)="selectSpec(masterStatusSpec)">{{masterStatusSpec.display_name}}</a>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngFor="let wfs of cat.workflow_specs" class="workflow-spec">
|
||||
<ng-container *ngTemplateOutlet="workflowSpecCard; context: {wfs: wfs, cat: cat}"></ng-container>
|
||||
</div>
|
||||
<div *ngIf="cat.workflow_specs.length === 0">No workflow specs in this category</div>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<mat-divider></mat-divider>
|
||||
<ng-container *ngIf="masterStatusSpec">
|
||||
<h1>Master Status Specification</h1>
|
||||
<ng-container *ngTemplateOutlet="workflowSpecCard; context: {wfs: masterStatusSpec, cat: null}"></ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<ng-template #workflowSpecCard let-wfs="wfs" let-cat="cat">
|
||||
<app-workflow-spec-card
|
||||
[workflowSpec]="wfs"
|
||||
[actionButtons]="actionButtons"
|
||||
(workflowUpdated)="onWorkflowUpdated($event)"
|
||||
></app-workflow-spec-card>
|
||||
<ng-template #actionButtons>
|
||||
<div class="workflow-spec-actions">
|
||||
<button mat-mini-fab title="Check for errors in this workflow specification" color="accent" (click)="validateWorkflowSpec(wfs)">
|
||||
<mat-icon>verified_user</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="cat && cat.workflow_specs.length > 0 && wfs.display_order !== 0"
|
||||
mat-mini-fab
|
||||
title="Move up"
|
||||
color="primary"
|
||||
(click)="editSpecDisplayOrder(wfs.id, -1, cat.workflow_specs)"
|
||||
>
|
||||
<mat-icon>arrow_upward</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="cat && cat.workflow_specs.length > 0 && (wfs.display_order < cat.workflow_specs.length - 1)"
|
||||
mat-mini-fab
|
||||
title="Move down"
|
||||
color="primary"
|
||||
(click)="editSpecDisplayOrder(wfs.id, 1, cat.workflow_specs)"
|
||||
>
|
||||
<mat-icon>arrow_downward</mat-icon>
|
||||
</button>
|
||||
<button mat-mini-fab title="Edit this workflow specification" color="primary" (click)="editWorkflowSpec(wfs)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button title="Delete this workflow specification" color="warn" (click)="confirmDeleteWorkflowSpec(wfs)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
<ng-container *ngFor="let cat of workflowSpecsByCategory">
|
||||
<ng-container *ngIf="!(cat.id === null && cat.workflow_specs.length === 0)">
|
||||
<div class="category" fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="start center">
|
||||
<h4>{{cat.display_name}} ({{cat.name}})</h4>
|
||||
<div class="category-actions" fxLayout="row" fxLayoutGap="10px" *ngIf="cat.id !== null">
|
||||
<button mat-mini-fab color="primary" (click)="editWorkflowSpecCategory(cat)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="cat.display_order > 0"
|
||||
mat-mini-fab
|
||||
title="Move up"
|
||||
color="primary"
|
||||
(click)="editCategoryDisplayOrder(cat.id, -1, workflowSpecsByCategory)"
|
||||
>
|
||||
<mat-icon>arrow_upward</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="cat.display_order < workflowSpecsByCategory.length - 2"
|
||||
mat-mini-fab
|
||||
title="Move down"
|
||||
color="primary"
|
||||
(click)="editCategoryDisplayOrder(cat.id, 1, workflowSpecsByCategory)"
|
||||
>
|
||||
<mat-icon>arrow_downward</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button title="Delete this category" color="warn"
|
||||
(click)="confirmDeleteWorkflowSpecCategory(cat)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<mat-list>
|
||||
<mat-list-item *ngFor="let wfs of cat.workflow_specs" class="workflow-spec" fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="start center">
|
||||
<a class="spec_menu_item" (click)="selectSpec(wfs)">{{wfs.display_name}}</a>
|
||||
<span class="spec-actions" fxLayout="row" fxLayoutGap="10px" *ngIf="cat.id !== null">
|
||||
<button
|
||||
*ngIf="cat && cat.workflow_specs.length > 0 && wfs.display_order !== 0"
|
||||
mat-mini-fab
|
||||
title="Move up"
|
||||
color="primary"
|
||||
(click)="editSpecDisplayOrder(wfs.id, -1, cat.workflow_specs)"
|
||||
>
|
||||
<mat-icon>arrow_upward</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
*ngIf="cat && cat.workflow_specs.length > 0 && (wfs.display_order < cat.workflow_specs.length - 1)"
|
||||
mat-mini-fab
|
||||
title="Move down"
|
||||
color="primary"
|
||||
(click)="editSpecDisplayOrder(wfs.id, 1, cat.workflow_specs)"
|
||||
>
|
||||
<mat-icon>arrow_downward</mat-icon>
|
||||
</button>
|
||||
</span>
|
||||
<!--
|
||||
<ng-container *ngTemplateOutlet="workflowSpecCard; context: {wfs: wfs, cat: cat}"></ng-container>
|
||||
-->
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
|
||||
<div *ngIf="cat.workflow_specs.length === 0">No workflow specs in this category</div>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</mat-drawer>
|
||||
|
||||
<div class="content">
|
||||
<ng-container *ngIf="selectedSpec">
|
||||
<ng-container *ngTemplateOutlet="workflowSpecCard; context: {wfs: selectedSpec, cat: null}"></ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
</mat-drawer-container>
|
||||
|
||||
|
||||
<ng-template #workflowSpecCard let-wfs="wfs" let-cat="cat">
|
||||
<app-workflow-spec-card
|
||||
[workflowSpec]="wfs"
|
||||
[actionButtons]="actionButtons"
|
||||
></app-workflow-spec-card>
|
||||
<ng-template #actionButtons>
|
||||
<div class="workflow-spec-actions">
|
||||
<button mat-mini-fab title="Check for errors in this workflow specification" color="accent"
|
||||
(click)="validateWorkflowSpec(wfs)">
|
||||
<mat-icon>verified_user</mat-icon>
|
||||
</button>
|
||||
<button mat-mini-fab title="Edit this workflow specification" color="primary" (click)="editWorkflowSpec(wfs)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button title="Delete this workflow specification" color="warn"
|
||||
(click)="confirmDeleteWorkflowSpec(wfs)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
@import "../../config";
|
||||
|
||||
|
||||
.container {
|
||||
padding: 3rem;
|
||||
}
|
||||
|
||||
.category {
|
||||
padding: 1rem 1rem 1rem 0;
|
||||
.content {
|
||||
min-height: 600px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 1rem 1rem 1rem 0;
|
||||
.category {
|
||||
padding: 1rem 1rem 0 0;
|
||||
|
||||
h4 {
|
||||
margin: 1rem 1rem 0 0;
|
||||
}
|
||||
|
||||
.category-actions {
|
||||
|
@ -22,8 +29,37 @@
|
|||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
.workflow-spec {
|
||||
border-left: 4px solid $brand-gray-light;
|
||||
&:hover {
|
||||
border-left: 4px solid $brand-primary;
|
||||
background-color: $brand-primary-tint-4;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
cursor: pointer;
|
||||
.spec_menu_item {
|
||||
flex-flow: row;
|
||||
display: inline-block;
|
||||
width: 300px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
.spec-actions {
|
||||
width: 100px;
|
||||
opacity: 0;
|
||||
}
|
||||
&:hover {
|
||||
.spec-actions {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.workflow-spec-actions {
|
||||
button {
|
||||
margin-right: 1em;
|
||||
|
|
|
@ -22,6 +22,10 @@ import {
|
|||
WorkflowSpecDialogData
|
||||
} from '../_interfaces/dialog-data';
|
||||
import {ApiErrorsComponent} from 'sartography-workflow-lib';
|
||||
import {ActivatedRoute} from '@angular/router';
|
||||
import {map} from 'rxjs/operators';
|
||||
import {Location} from '@angular/common';
|
||||
import {environment} from '../../environments/environment.runtime';
|
||||
|
||||
|
||||
export interface WorkflowSpecCategoryGroup {
|
||||
|
@ -51,12 +55,20 @@ export class WorkflowSpecListComponent implements OnInit {
|
|||
private api: ApiService,
|
||||
private snackBar: MatSnackBar,
|
||||
private bottomSheet: MatBottomSheet,
|
||||
public dialog: MatDialog
|
||||
public dialog: MatDialog,
|
||||
private route: ActivatedRoute,
|
||||
private location: Location
|
||||
) {
|
||||
this._loadWorkflowSpecCategories();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.route.paramMap.subscribe(paramMap => {
|
||||
if (paramMap.has('spec')) {
|
||||
this._loadWorkflowSpecCategories(paramMap.get('spec'));
|
||||
} else {
|
||||
this._loadWorkflowSpecCategories();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
validateWorkflowSpec(wfs: WorkflowSpec) {
|
||||
|
@ -69,6 +81,11 @@ export class WorkflowSpecListComponent implements OnInit {
|
|||
});
|
||||
}
|
||||
|
||||
selectSpec(selectedSpec?: WorkflowSpec) {
|
||||
this.selectedSpec = selectedSpec;
|
||||
this.location.replaceState(environment.homeRoute + '/' + selectedSpec.name);
|
||||
}
|
||||
|
||||
editWorkflowSpec(selectedSpec?: WorkflowSpec) {
|
||||
this.selectedSpec = selectedSpec;
|
||||
const hasDisplayOrder = this.selectedSpec && isNumberDefined(this.selectedSpec.display_order);
|
||||
|
@ -159,7 +176,7 @@ export class WorkflowSpecListComponent implements OnInit {
|
|||
|
||||
sortByDisplayOrder = (a, b) => (a.display_order < b.display_order) ? -1 : 1;
|
||||
|
||||
private _loadWorkflowSpecCategories() {
|
||||
private _loadWorkflowSpecCategories(selectedSpecName: string = null) {
|
||||
this.api.getWorkflowSpecCategoryList().subscribe(cats => {
|
||||
this.categories = cats.sort(this.sortByDisplayOrder);
|
||||
|
||||
|
@ -177,13 +194,15 @@ export class WorkflowSpecListComponent implements OnInit {
|
|||
this.workflowSpecsByCategory[i + 1].workflow_specs = [];
|
||||
});
|
||||
|
||||
this._loadWorkflowSpecs();
|
||||
this._loadWorkflowSpecs(selectedSpecName);
|
||||
});
|
||||
}
|
||||
|
||||
private _loadWorkflowSpecs() {
|
||||
private _loadWorkflowSpecs(selectedSpecName: String = null) {
|
||||
|
||||
this.api.getWorkflowSpecList().subscribe(wfs => {
|
||||
this.workflowSpecs = wfs;
|
||||
|
||||
this.workflowSpecsByCategory.forEach(cat => {
|
||||
cat.workflow_specs = this.workflowSpecs
|
||||
.filter(wf => {
|
||||
|
@ -195,6 +214,20 @@ export class WorkflowSpecListComponent implements OnInit {
|
|||
})
|
||||
.sort(this.sortByDisplayOrder);
|
||||
});
|
||||
|
||||
// Set the selected workflow to something sensible.
|
||||
if (!selectedSpecName && this.selectedSpec) {
|
||||
selectedSpecName = this.selectedSpec.name;
|
||||
}
|
||||
if (selectedSpecName) {
|
||||
this.workflowSpecs.forEach(ws => {
|
||||
if (selectedSpecName && selectedSpecName === ws.name) {
|
||||
this.selectedSpec = ws;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.selectedSpec = this.masterStatusSpec;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -251,7 +284,7 @@ export class WorkflowSpecListComponent implements OnInit {
|
|||
|
||||
private _addWorkflowSpec(newSpec: WorkflowSpec) {
|
||||
this.api.addWorkflowSpecification(newSpec).subscribe(_ => {
|
||||
this._loadWorkflowSpecs();
|
||||
this._loadWorkflowSpecs(newSpec.name);
|
||||
this._displayMessage('Saved new workflow spec.');
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue