wf ui
This commit is contained in:
parent
f4399909a6
commit
a855a6afff
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>eu.dnetlib.dhp</groupId>
|
||||
<artifactId>apps</artifactId>
|
||||
<version>3.3.3-SNAPSHOT</version>
|
||||
<version>3.4.1-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -28,7 +28,12 @@ public class WfHistoryAjaxController extends AbstractDnetController {
|
|||
return logger.history(total, from, to);
|
||||
}
|
||||
|
||||
@GetMapping("/{processId}")
|
||||
@GetMapping("/byConf/{wfConfId}")
|
||||
public List<WfHistoryEntry> history(@PathVariable final String wfConfId) {
|
||||
return logger.history(wfConfId);
|
||||
}
|
||||
|
||||
@GetMapping("/proc/{processId}")
|
||||
public WfHistoryEntry getProcessExecution(@PathVariable final String processId) {
|
||||
return logger.getLog(processId);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ import { SpinnerHttpInterceptor } from './common/spinner.service';
|
|||
import { MdstoresComponent, MdstoreInspectorComponent, MDStoreVersionsDialog, AddMDStoreDialog } from './mdstores/mdstores.component';
|
||||
import { CleanerTesterComponent } from './cleaner-tester/cleaner-tester.component';
|
||||
import { EmailDialog, EmailsComponent } from './emails/emails.component';
|
||||
import { WfConfsComponent, WfConfDialog } from './wf-confs/wf-confs.component';
|
||||
import { WfConfsComponent, WfConfDialog, WfConfSingle } from './wf-confs/wf-confs.component';
|
||||
import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatStepperModule } from '@angular/material/stepper';
|
||||
|
@ -75,7 +75,8 @@ import { MatStepperModule } from '@angular/material/stepper';
|
|||
EmailsComponent,
|
||||
EmailDialog,
|
||||
WfConfsComponent,
|
||||
WfConfDialog
|
||||
WfConfDialog,
|
||||
WfConfSingle
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
|
|
@ -74,6 +74,10 @@ export class ISService {
|
|||
this.httpGetWithOptions<WfHistoryEntry[]>('/ajax/wf_history/', { params: params }, onSuccess);
|
||||
}
|
||||
|
||||
loadWfHistoryForConf(wfConfId: string, onSuccess: Function): void {
|
||||
this.httpGet<WfHistoryEntry[]>('/ajax/wf_history/byConf/' + encodeURIComponent(wfConfId), onSuccess);
|
||||
}
|
||||
|
||||
loadContexts(onSuccess: Function): void {
|
||||
this.httpGet<Context[]>('./ajax/contexts/', onSuccess);
|
||||
}
|
||||
|
|
|
@ -39,14 +39,12 @@
|
|||
}
|
||||
|
||||
.menu-count {
|
||||
padding-top: 0.3em;
|
||||
padding-bottom: 0.3em;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
border-radius: 0.2em;
|
||||
font-size: 0.6em;
|
||||
border-radius: 1em;
|
||||
font-size: 0.7em;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
float: right;
|
||||
width: 3em;
|
||||
width: 2em;
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
<p>You are now done.</p>
|
||||
<div>
|
||||
<form [formGroup]="wfConfFormFinal" (ngSubmit)="onSubmit()">
|
||||
<button mat-stroked-button color="primary" type="submit">Submit</button>
|
||||
<button mat-stroked-button color="primary" type="submit">Save</button>
|
||||
<mat-error *ngIf="wfConfFormFinal.errors?.['serverError']">
|
||||
{{ wfConfFormFinal.errors?.['serverError'] }}
|
||||
</mat-error>
|
||||
|
@ -102,7 +102,3 @@
|
|||
</mat-step>
|
||||
</mat-vertical-stepper>
|
||||
</div>
|
||||
|
||||
<div mat-dialog-actions>
|
||||
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
<div *ngIf="conf" style="padding: 16px; margin-top: 0.4em; border: 1px solid lightgray; border-radius: 8px;">
|
||||
|
||||
<h2>{{conf.name}}</h2>
|
||||
<span *ngIf="conf.dsName"><b>Datasource Name:</b> {{conf.dsName}}<br /></span>
|
||||
<span *ngIf="conf.dsId"><b>Datasource ID:</b> {{conf.dsId}}<br /></span>
|
||||
<span *ngIf="conf.apiId"><b>Datasource API:</b> {{conf.apiId}}<br /></span>
|
||||
|
||||
<button mat-stroked-button color="primary" (click)="launchWfConf()">
|
||||
<mat-icon fontIcon="play_circle"></mat-icon>
|
||||
launch
|
||||
</button>
|
||||
<button mat-stroked-button color="primary" (click)="editConf()">
|
||||
<mat-icon fontIcon="edit"></mat-icon>
|
||||
configure
|
||||
</button>
|
||||
<a href="./api/resources/{{conf.workflow}}/content" mat-stroked-button color="link" target="_blank">
|
||||
<mat-icon fontIcon="code"></mat-icon>
|
||||
raw workflow
|
||||
</a>
|
||||
<button mat-stroked-button color="warn" (click)="deleteConf()">
|
||||
<mat-icon fontIcon="delete"></mat-icon>
|
||||
delete
|
||||
</button>
|
||||
|
||||
<mat-divider style="margin-top: 1em; margin-bottom: 1em;"></mat-divider>
|
||||
|
||||
<table mat-table [dataSource]="historyDatasource" matSort>
|
||||
|
||||
<ng-container matColumnDef="processId">
|
||||
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header
|
||||
sortActionDescription="Sort by Process ID"> Process Id </th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<a (click)="openWfHistoryDialog(element)">{{element.processId}}</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="status">
|
||||
<th mat-header-cell *matHeaderCellDef style="width: 10%;" mat-sort-header sortActionDescription="Sort by Status">
|
||||
Status </th>
|
||||
<td mat-cell *matCellDef="let element"><span class="badge-label"
|
||||
[ngClass]="{'badge-success' : element.status === 'success', 'badge-failure' : element.status === 'failure'}">{{element.status}}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="startDate">
|
||||
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header
|
||||
sortActionDescription="Sort by Start Date"> Start Date </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.startDate}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="endDate">
|
||||
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header
|
||||
sortActionDescription="Sort by End Date">
|
||||
End Date </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.endDate}} </td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="colums"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: colums;"></tr>
|
||||
|
||||
<!-- Row shown when there is no matching data. -->
|
||||
<tr class="mat-row" *matNoDataRow>
|
||||
<td class="mat-cell" colspan="4" style="padding: 0 16px;">No execution in history"</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- <pre>{{conf | json}}</pre> -->
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="!conf" style="margin-top: 2em;">
|
||||
Workflow Configuration does not exist
|
||||
</div>
|
|
@ -12,27 +12,4 @@
|
|||
</a>
|
||||
</nav>
|
||||
|
||||
<div *ngIf="conf" style="margin-top: 2em;">
|
||||
<button mat-stroked-button color="primary" (click)="launchWfConf()">
|
||||
<mat-icon fontIcon="play_circle"></mat-icon>
|
||||
launch
|
||||
</button>
|
||||
<button mat-stroked-button color="primary" (click)="editConf()">
|
||||
<mat-icon fontIcon="edit"></mat-icon>
|
||||
configure
|
||||
</button>
|
||||
<a href="./api/resources/{{conf.workflow}}/content" mat-stroked-button color="link" target="_blank">
|
||||
<mat-icon fontIcon="code"></mat-icon>
|
||||
raw workflow
|
||||
</a>
|
||||
<button mat-stroked-button color="warn" (click)="deleteConf()">
|
||||
<mat-icon fontIcon="delete"></mat-icon>
|
||||
delete
|
||||
</button>
|
||||
<pre>{{conf | json}}</pre>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="!conf" style="margin-top: 2em;">
|
||||
Workflow Configuration does not exist
|
||||
</div>
|
||||
<wf-conf-single [conf]="conf"></wf-conf-single>
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import { JsonPipe } from '@angular/common';
|
||||
import { Component, Inject, OnInit, SecurityContext } from '@angular/core';
|
||||
import { Component, Inject, Input, OnChanges, OnInit, SecurityContext, SimpleChanges } from '@angular/core';
|
||||
import { FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
|
||||
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { MatSelectChange } from '@angular/material/select';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { KeyValue, SimpleResource, WfConf, WfParam, WfProcessStatus, WfSection } from '../common/is.model';
|
||||
import { KeyValue, SimpleResource, WfConf, WfHistoryEntry, WfParam, WfProcessStatus, WfSection } from '../common/is.model';
|
||||
import { ISService } from '../common/is.service';
|
||||
import { ResMetadataDialog } from '../resources/resources.component';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { WfHistoryDialog } from '../wf-history/wf-history.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-wf-confs',
|
||||
|
@ -73,34 +75,6 @@ export class WfConfsComponent implements OnInit {
|
|||
if (result) this.router.navigate(['/wfs/conf', result.id]);;
|
||||
});
|
||||
}
|
||||
|
||||
launchWfConf() {
|
||||
if (this.conf?.id && this.conf?.workflow) {
|
||||
this.service.startWfConfiguration(this.conf?.id, (data: WfProcessStatus) => this.snackBar.open('Workflow launched !!!', 'INFO', { duration: 5000 }));
|
||||
}
|
||||
}
|
||||
|
||||
editConf() {
|
||||
const dialogRef = this.dialog.open(WfConfDialog, {
|
||||
data: this.conf,
|
||||
width: '80%'
|
||||
});
|
||||
}
|
||||
|
||||
deleteConf() {
|
||||
if (this.conf?.destroyWf) {
|
||||
if (this.conf?.id && this.conf?.workflow) {
|
||||
this.service.startDestroyWfConfiguration(this.conf?.id, (data: WfProcessStatus) => this.snackBar.open('Destroy Workflow launched, PLEASE WAIT !!!', 'INFO', { duration: 5000 }));
|
||||
}
|
||||
} else if (this.conf?.id) {
|
||||
this.service.deleteWfConfiguration(this.conf?.id, (data: void) => {
|
||||
this.snackBar.open('Configuration deleted !!!', 'INFO', { duration: 5000 });
|
||||
this.conf = undefined;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
@ -108,7 +82,6 @@ export class WfConfsComponent implements OnInit {
|
|||
templateUrl: 'wf-conf-dialog.html',
|
||||
styleUrls: ['./wf-confs.component.css']
|
||||
})
|
||||
|
||||
export class WfConfDialog implements OnInit {
|
||||
|
||||
wfTemplates: SimpleResource[] = [];
|
||||
|
@ -195,3 +168,67 @@ export class WfConfDialog implements OnInit {
|
|||
this.dialogRef.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'wf-conf-single',
|
||||
templateUrl: 'wf-conf-single.html',
|
||||
styleUrls: ['./wf-confs.component.css']
|
||||
})
|
||||
export class WfConfSingle implements OnInit, OnChanges {
|
||||
|
||||
@Input() conf?: WfConf;
|
||||
prevConfId = '';
|
||||
|
||||
historyDatasource: MatTableDataSource<WfHistoryEntry> = new MatTableDataSource<WfHistoryEntry>([]);
|
||||
colums: string[] = ['processId', 'status', 'startDate', 'endDate'];
|
||||
|
||||
constructor(public service: ISService, public dialog: MatDialog, public snackBar: MatSnackBar) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.conf) {
|
||||
this.service.loadWfHistoryForConf(this.conf?.id, (data: WfHistoryEntry[]) => this.historyDatasource.data = data);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (this.conf && this.conf.id != this.prevConfId) {
|
||||
this.prevConfId = this.conf.id;
|
||||
this.service.loadWfHistoryForConf(this.conf?.id, (data: WfHistoryEntry[]) => this.historyDatasource.data = data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
launchWfConf() {
|
||||
if (this.conf?.id && this.conf?.workflow) {
|
||||
this.service.startWfConfiguration(this.conf?.id, (data: WfProcessStatus) => this.snackBar.open('Workflow launched !!!', 'INFO', { duration: 5000 }));
|
||||
}
|
||||
}
|
||||
|
||||
editConf() {
|
||||
const dialogRef = this.dialog.open(WfConfDialog, {
|
||||
data: this.conf,
|
||||
width: '80%'
|
||||
});
|
||||
}
|
||||
|
||||
deleteConf() {
|
||||
if (this.conf?.destroyWf) {
|
||||
if (this.conf?.id && this.conf?.workflow) {
|
||||
this.service.startDestroyWfConfiguration(this.conf?.id, (data: WfProcessStatus) => this.snackBar.open('Destroy Workflow launched, PLEASE WAIT !!!', 'INFO', { duration: 5000 }));
|
||||
}
|
||||
} else if (this.conf?.id) {
|
||||
this.service.deleteWfConfiguration(this.conf?.id, (data: void) => {
|
||||
this.snackBar.open('Configuration deleted !!!', 'INFO', { duration: 5000 });
|
||||
this.conf = undefined;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
openWfHistoryDialog(wf: WfHistoryEntry): void {
|
||||
const wfDialogRef = this.dialog.open(WfHistoryDialog, {
|
||||
data: wf
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<span><b>Count :</b> {{historyDatasource.filteredData.length}}</span>
|
||||
</p>
|
||||
|
||||
<table mat-table [dataSource]="historyDatasource" matSort class="mat-elevation-z8">
|
||||
<table mat-table [dataSource]="historyDatasource" matSort>
|
||||
|
||||
<ng-container matColumnDef="processId">
|
||||
<th mat-header-cell *matHeaderCellDef style="width: 15%;" mat-sort-header
|
||||
|
@ -70,6 +70,6 @@
|
|||
|
||||
<!-- Row shown when there is no matching data. -->
|
||||
<tr class="mat-row" *matNoDataRow>
|
||||
<td class="mat-cell" colspan="4" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
||||
<td class="mat-cell" colspan="7" style="padding: 0 16px;">No data matching the filter "{{input.value}}"</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>eu.dnetlib.dhp</groupId>
|
||||
<artifactId>libs</artifactId>
|
||||
<version>3.3.3-SNAPSHOT</version>
|
||||
<version>3.4.1-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>eu.dnetlib.dhp</groupId>
|
||||
<artifactId>libs</artifactId>
|
||||
<version>3.3.3-SNAPSHOT</version>
|
||||
<version>3.4.1-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>eu.dnetlib.dhp</groupId>
|
||||
<artifactId>apps</artifactId>
|
||||
<version>3.3.3-SNAPSHOT</version>
|
||||
<version>3.4.1-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -36,6 +36,10 @@ public class WorkflowLogger {
|
|||
}
|
||||
}
|
||||
|
||||
public List<WfHistoryEntry> history(final String wfConfId) {
|
||||
return wfHistoryEntryRepository.findByWfConfigurationIdOrderByEndDateDesc(wfConfId);
|
||||
}
|
||||
|
||||
public WfHistoryEntry getLog(final String processId) {
|
||||
return wfHistoryEntryRepository.findById(processId).get();
|
||||
}
|
||||
|
|
|
@ -12,5 +12,7 @@ public interface WfHistoryEntryRepository extends JpaRepository<WfHistoryEntry,
|
|||
|
||||
List<WfHistoryEntry> findByEndDateBetweenOrderByEndDateDesc(LocalDateTime start, LocalDateTime end);
|
||||
|
||||
List<WfHistoryEntry> findByWfConfigurationIdOrderByEndDateDesc(String id);
|
||||
|
||||
Optional<WfHistoryEntry> findFirstByWfConfigurationIdOrderByEndDateDesc(String id);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<groupId>eu.dnetlib.dhp</groupId>
|
||||
<artifactId>libs</artifactId>
|
||||
<version>3.3.3-SNAPSHOT</version>
|
||||
<version>3.4.1-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
Loading…
Reference in New Issue